如果我想在C ++中克隆多态对象(即从其他B类派生的A类实例),最简单的方法似乎是给B一个虚拟克隆成员函数,必须由A看起来像这样
A* clone(){
return new A(*this);
}
我的问题是,我发现这个不必要的样板代码,因为如果想要使用C ++的运行时多态特性,几乎总是需要它。如何规避?
由于
为什么我需要这个:
我的用例可以抽象为以下示例:
我有一个class Integral
,它评估某个函数的积分。这样做,他们有一个指向class MathFunction
的成员。此抽象类包含一个纯虚函数evaluate
,它接受一个参数。我想实现我将创建class PowFunction : class MathFunction
的幂函数。这个类有一个成员exponent
,函数evaluate看起来像这样:
double evaluate(x){
return pow(x,exponent);
}
如上所述,MathFunction
的成员class Integral
必须是多态的,这要求它是一个指针。用另一个问题回答评论者的问题。为什么我不想复制MathFunction对象?
我真的希望Integral“拥有”它的MathFunction,这意味着它可以改变参数(如exponent
),而无需更改任何其他Integral对象的MathFunction。这意味着每个Integral都需要拥有自己的副本。这需要MathFunctions的clone()函数,不是吗?
我想到的另一个选择:如果几个Integral对象可以通过指向同一地址的指针共享相同的MathFunction,我可以创建Integral对象的副本而无需复制MathFunction。但在这种情况下,我将不得不使所有的属性const或某种方式readonly,这也不是很优雅。另外,哪个Integral对象应该处理删除MathFunction对象?
为什么需要这个:
您是否认真地说,只要您处理多态对象,就不需要复制操作?是什么让多态对象在这方面与其他对象不同?
使用这个论证,您也可以将复制构造函数和复制赋值运算符抛出C ++标准!
答案 0 :(得分:9)
减少克隆多态对象的需要。真的,我很少在我自己的代码中找到这个需求,并且对这个问题的评论表明我并不孤单,如果你发现自己克隆了所有内容,那么你可能设计错了。
当然,永远不要无益,你确实可以使用奇怪的重复模板模式。
template<typename T> struct Clone {
virtual T* clone() { return new T(static_cast<const T&>(*this)); }
};
答案 1 :(得分:3)
我用宏来处理这个问题...它很难看,但它可以避免不一致。
/** An interface that can be inherited by any class that wants to provide a Clone()
* method that will return a copy of itself.
*/
class ICloneable
{
public:
ICloneable() {}
virtual ~ICloneable() {}
virtual ICloneable * Clone() const = 0;
};
#define DECLARE_STANDARD_CLONE_METHOD(class_name) virtual ICloneable * Clone() const {new class_name(*this);}
[...]
public MyCloneableClass : public ICloneable
{
public:
MyCloneableClass() {}
DECLARE_STANDARD_CLONE_METHOD(MyCloneableClass);
};