我有一个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_是公共的,这不是理想的,也不是很好的编程风格。我认为可能使用友元类或函数的方法可以通过访问变量来渗透类,同时仍然保持基类抽象?任何人都可以解释这是如何工作的?
答案 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& );
};
答案 1 :(得分:1)
我相信如果不将Archive
类型参数以这种方式包装到多态层次结构中,你就无法做到。
似乎Boost.Serialization
does it for you。
答案 2 :(得分:1)
您可能知道template
和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
内调用的非虚拟方法 - &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元编程库来为此问题提供运行时解决方案。