コンテキストと抽象型の割り当てを避ける:私はブーストからのアーカイブの同様の方法で、データのアーカイブのためのいくつかのツールを書きました。テンプレート
class A
{
private:
double a;
public:
A() : a(3.14159)
{}
A(const A& a_) : a(a_.a) {}
virtual ~A()
{}
virtual A* clone() const = 0; // Then, A is virtual
virtual void save(O_Archive& oa) const //
{ //
oa << this->a; // INTERESTING
} // PART OF THE
virtual void load(I_archive& ia) // CLASS
{ //
ia >> this->a; //
} //
};
O_Archive& operator << (O_Archive& oa, const A& a)
{
a.save(oa);
return oa;
}
I_Archive& operator >> (I_Archive& ia, A& a)
{
a.load(ia);
return ia;
}
class B : public A
{
private:
double b;
public:
B() : A(), b(1.0) {}
B(const B& b_) : A(b_), b(b_.b) {}
virtual ~B() {}
virtual A* clone() const
{
return new B(*this);
}
void save(O_Archive& oa) const //
{ //
this->A::save(oa); //
oa << this->b; // INTERESTING
} // PART OF THE
void load(I_Archive& ia) // CLASS
{ //
this->A::load(ia); //
ia >> this->b; //
} //
};
// Consider classes 'C' and 'D' similar to 'B'
void example_save(O_Archive& oa)
{
A* p1 = new B;
A* p2 = new C;
D* p3 = new D;
oa << Archive::declare_derived<A,B,C,D>();
oa << p1 << p2; // Automatically detect the inheritance
oa << p3; // Store the instance as a usual pointer
}
void example_load(I_Archive& ia)
{
A* p1 = 0;
A* p2 = 0;
B* p3 = 0;
ia << Archive::declare_derived<A,B,C,D>();
ia >> p1 >> p2;
ia >> p3;
}
問題は次のとおりです。次に、例として、私はこの種のコードを書くことができますか?それが派生タイプ、又は単に通常のポインタでインスタンスした場合、ポインタが、割り当てられた場合、このチェックの担当クラスI_Archive
で次load_pointer
機能のようないくつかの機能と連動。
template <typename T>
void I_Archive::load_pointer(T*& p)
{
delete p;
bool allocated;
this->load_bool(allocated);
if(allocated)
{
bool inheriance;
this->load_bool(inheriance);
if(inheriance)
{
unsigned long int i;
this->load_unsigned_long_int(i);
p = boost::static_pointer_cast< const Archive::allocator<T> >(this->alloc[&typeid(T)][i])->allocate();
}
else
p = new T; // ERROR AT THIS LINE
*this >> *p;
}
else
p = 0;
}
私の問題:実は、私のコードは、行p = new T;
上の次のエラーでコンパイルできません:
error: cannot allocate an object of abstract type ‘A’.
私が最初に驚いたが、私が持っている理由私は本当によく理解してこのエラー:機能load_pointer
がp1
に呼び出されたときに、命令new T
はタイプがABSがある場合、命令は実行されない場合であっても、禁止されているnew A
になりますトラクト。
私の質問:テンプレートを正しく使用してエラーを回避する方法が見つかりません。可能性のある回避策がありますか、コンパイラに言わせると"私は何をしているのか分かりません。抽象型をインスタンス化する必要はありません"?
重要な注記:互換性の理由からC++ 11では動作しません。あなたが探している
ケースの失敗でT 'は 'A'ある'入力表示されます。 –
たぶん、あなたは単にあなたがA. –
@ThomasBenardに固有のものを置くことが可能なAの特殊なケースのためにあなたの 'load_pointer'関数をオーバーロードすることができます:それは、アプリケーションのすべての抽象クラスを知るためにArchive''のresponsabilityではありません。つまり、新しい抽象クラスを追加するたびに 'Archive'クラスを編集しなければならないことを意味します。それは非常に悪いデザインです。 – Caduchon