如果我有一个指向从抽象基类派生的对象的指针(因此我无法创建该类的新对象),并且我希望制作所述对象的深层副本,是否有比使抽象基类创建每个继承类都必须实现新的纯虚拟copy 函数更简明的方法?
如果我有一个指向从抽象基类派生的对象的指针(因此我无法创建该类的新对象),并且我希望制作所述对象的深层副本,是否有比使抽象基类创建每个继承类都必须实现新的纯虚拟copy 函数更简明的方法?
不,但是copy
方法并不一定很痛苦:
class Derived : public Base
{
public:
Base *copy() const
{
return new Derived(*this);
}
};
(假设您已经有了一个拷贝构造函数,如果需要深拷贝,您就会有这个函数)。
copy
方法定义为纯虚函数,这样编译器会在你忘记提供它时告诉你。 - Mark Ransomstruct Abc
{
virtual void who() const = 0;
};
struct A : Abc
{
virtual void who() const { std::cout << "A" << std::endl;}
};
template<class T>
Abc* clone(Abc* abc)
{
T* t = dynamic_cast<T*>(abc);
if (t == 0)
return 0;
return new T(*t);
}
struct B : Abc
{
virtual void who() const { std::cout << "B" << std::endl;}
};
typedef Abc* (*Cloner)(Abc*);
std::map<std::string, Cloner> clones;
void defineClones()
{
clones[ typeid (A).name() ] = &clone<A>;
clones[ typeid (B).name() ] = &clone<B>;
}
Abc* clone(Abc* abc)
{
Abc* ret = 0;
const char* typeName = typeid(*abc).name();
if (clones.find(typeName) != clones.end())
{
Cloner cloner = clones[typeName];
ret = (*cloner)(abc);
}
return ret;
}
void test ()
{
defineClones();
Abc* a = new A;
Abc* anotherA = clone(a);
anotherA->who();
Abc* b = new B;
Abc* anotherB = clone(b);
anotherB->who();
}
虽然上述方法可行,但它使用了RTTI,这足以说服大多数人采用正常的方法。然而,如果有什么原因阻止对基类进行更改,那么这种方法可能会很有用。
这个方法有效吗?添加新类型的边际成本确实只有一行代码。问题在于,很容易忘记在每个新类中添加该行代码。或者你可以把它看作是一个优点,所有克隆代码都存在于单个文件中,我们不必更改支持的层次结构来处理它。