如果我有一个指向派生自抽象基类的对象的指针(因此我无法创建该类的新对象),并且我希望制作所述对象的深层副本,是否有比实现该对象更简洁的方法让抽象基类创建一个新的纯虚copy
函数,每个继承类都必须实现?
问问题
4842 次
3 回答
10
不,但该copy
方法不一定是痛苦的:
class Derived : public Base
{
public:
Base *copy() const
{
return new Derived(*this);
}
};
(假设你已经有一个拷贝构造函数,如果你需要一个深拷贝,你就会有)。
于 2011-01-21T03:38:47.413 回答
1
建议的“复制”,通常称为“克隆”是正常的方法。另一种方法是使用 rtti 进行工厂和调度以找到正确的处理程序,然后在派生类型上调用复制构造函数。
struct 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 的绝对事实足以说服大多数人采用正常方法。但是,阻止更改基类是有原因的,它可能很有用。
这么有效率?添加新类型的边际成本确实是单线的。问题是很容易忘记在每个新类中添加该行。或者您可以将其视为所有克隆代码都位于单个文件中的好处,我们不必更改支持的层次结构来处理它。
于 2011-01-21T03:39:53.027 回答
1
不久前,comp.lang.c++ 中的某个人询问了如何自动创建 clone() 函数。其他人提供了一个想法,我对此进行了扩展。它都不是经过测试的代码,我从未真正尝试过......但我认为它有效: http ://groups.google.com/group/comp.lang.c++/browse_thread/thread/c01181365d327b2f/9c99f46a8a64242e?hl =en&ie=UTF-8&oe=utf-8&q=comp.lang.c%2B%2B+noah+roberts+clone&pli=1
于 2011-01-21T04:28:20.850 回答