4

我有一个 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_ ,这并不理想,也不是良好的编程风格。我认为潜在的使用友元类或函数的方法可以通过访问变量来穿透类,同时仍然保持基类抽象?谁能解释这将如何工作?

4

5 回答 5

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

于 2012-05-11T15:52:22.017 回答
1

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

似乎Boost.Serialization 这对你有用

于 2012-05-07T23:29:54.577 回答
1

您可能知道templates 和virtual方法不能齐头并进。

我建议删除该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句柄 --> 调用的任何非虚拟方法在 的所有子类中都应具有相同的名称pointAccumulator,无论它们在内部做什么。

于 2012-05-11T04:29:24.220 回答
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$ 
于 2012-05-14T18:25:20.063 回答
1

所以我有一种有趣的方式来为模板化的函数伪造虚拟化。伪造一个虚拟模板函数c ++

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

于 2012-05-16T04:42:16.710 回答