虚函数和模板冲突

时间:2012-05-07 22:56:39

标签: c++ templates abstract-class boost-serialization

我有一个pointAccumulator的抽象基类。这个抽象基础将填充方法,例如返回所有点的平均值的函数。这两个类的示例如下所示:

class lala {
public:
    virtual someFunctions = 0;

    virtual bool isEmpty() = 0;
};


class lalaLower : public lala {
public:
    lalaLower(){}
    ~lalaLower(){}


    someFunctions

    template<class Archive> void serialize(Archive & ar, const unsigned int version) {
        ar & heights_;
    }

protected:
    std::deque<double> heights_;
};

正如您在代码中看到的,我还想使用boost序列化来保存这些类型。现在使用工厂模式我相信你调用pointAccumulator类型如下:

lala *a1 = new lalaLower();

我的问题是如果我以这种方式调用它,则无法访问模板化的序列化方法。此外,我不能在抽象类中使用模板化类,因为c ++不允许这样做。有办法解决这个问题吗?

编辑:

我已经考虑过序列化的非侵入式方法,但是要求heights_是公共的,这不是理想的,也不是很好的编程风格。我认为可能使用友元类或函数的方法可以通过访问变量来渗透类,同时仍然保持基类抽象?任何人都可以解释这是如何工作的?

5 个答案:

答案 0 :(得分:2)

我认为使用好友类或函数是一个很好的解决方案,你可以添加像Serializor

这样的新类

这是朋友功能的一个例子

class Serializor;
class meanAccumulator : public pointAccumulator 
{ 
public:     
meanAccumulator(){}     
~meanAccumulator(){}     
double getHeight();     
void addHeight(double Height);     
void setHeight(double Height);     
bool isEmpty(){ return heights_.empty(); }      

protected:     std::deque<double> heights_; 
friend int Serializor::Func1( Serializor& );

};

参考http://msdn.microsoft.com/en-us/library/ahhw8bzz.aspx

答案 1 :(得分:1)

我相信如果不将Archive类型参数以这种方式包装到多态层次结构中,你就无法做到。

似乎Boost.Serialization does it for you

答案 2 :(得分:1)

您可能知道templatevirtual方法不是齐头并进的。

我建议删除meanAccumulator::serialize()方法并添加到class pointAccumulator正文中,并在需要的任何地方调用virtual函数。
您还可以考虑传递派生类的句柄并使用该句柄调用该方法。

class pointAccumulator {
public:
  template<class Archive, class Derived>
  void serialize(Archive & ar, const unsigned int version, Derived &derived)
  {                                            // optional ^^^^^^^^^^^^^^^^^
    // call virtual methods to derived from here
    // optional: for non-virtual method, you can use derived class handle
  }
};

您唯一需要注意的是,使用serialize()句柄在derived内调用的非虚拟方法 - &gt;在pointAccumulator的所有子课程中都应该是同名的,无论他们在里面做什么。

答案 3 :(得分:1)

事实上,我会将我的评论作为答案:

~/src/snips$ cat serializer-demo.cc 
#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/archive/polymorphic_oarchive.hpp>

typedef boost::archive::polymorphic_iarchive bpi;
typedef boost::archive::polymorphic_oarchive bpo;
typedef const unsigned int cui;

struct ABC
{
        virtual void serialize(bpi &ar, cui v) = 0;
        virtual void serialize(bpo &ar, cui v) = 0;
};

struct A : ABC
{
        void serialize(bpi &ar, cui v ) { ar & data; }
        void serialize(bpo &ar, cui v ) { ar & data; }
        int data;
        bool operator==(const A & rhs) const
                { return data == rhs.data; }
        A(int data=0) : data(data) {}
};

#include <sstream>
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>

#include <boost/archive/polymorphic_binary_iarchive.hpp>
#include <boost/archive/polymorphic_binary_oarchive.hpp>
int main(int argc, char* argv[])
{
    const A a(1);
    const ABC &abc = a;
    A a1;
    ABC &abc1 = a1;
    {
        std::stringstream ss;
        {
            boost::archive::polymorphic_text_oarchive oa(ss);
            boost::archive::polymorphic_oarchive & oa_interface = oa; 
            oa_interface << abc;
        }
        {
            boost::archive::polymorphic_text_iarchive ia(ss);
            ia >> abc1;
        }
    }
    if(! (a == a1))
        return 1;
    {
        std::stringstream ss;
        {
            boost::archive::polymorphic_binary_oarchive oa(ss);
            oa << abc;
        }
        {
            boost::archive::polymorphic_binary_iarchive ia(ss);
            boost::archive::polymorphic_iarchive & ia_interface = ia; 
            ia_interface >> abc1;
        }
    }
    if(! (a == a1))
        return 1;
    return 0;
}

~/src/snips$ make -B serializer-demo
g++ -o bin/serializer-demo --std=c++0x -g -O -march=native -pipe -Wall -Wno-parentheses   -lboost_serialization  serializer-demo.cc
~/src/snips$ type -pa serializer-demo
./bin/serializer-demo
~/src/snips$ serializer-demo
~/src/snips$ echo $?
0
~/src/snips$ 

答案 4 :(得分:1)

所以我有一种有趣的方法来伪造模板化虚函数。 Faking a virtual templated function c++

如果您需要在层次结构中强制执行此操作,则可以在此处应用基本动机,但您可以使用boost元编程库来为此问题提供运行时解决方案。