我有一个抽象类说Figure
和一些派生类:Circle
,Square
,...
类图实现:
private:
virtual double varea()=0;
double multiplier;
public:
virtual Figure * clone()=0;
double area() { return varea()*multiplier; }
例如,Square的数字表现得像这样:
private:
double L;
public:
virtual Figure * clone() {return new Square(*this);}
virtual double varea() {return L*L;}
在调用方法clone时,我很难分配变量乘数。实现这一目标的最佳方法是什么?当然这只是一个愚蠢的例子,有许多变通方法,但实际上,有多个派生级别,它们并不那么明显,所以请坚持这种模式。
我是否应该为方法克隆寻找虚拟接口?通过这种方式,我可以直接在Figure类中分配乘数,而无需让每个数字都知道它的乘数。
答案 0 :(得分:1)
除非你为你的类声明一个复制构造函数图语言给你一个 au gratis ,它是公开的。你不想要这个免费的公共拷贝构造函数。它会导致切片。为类图保护你的复制构造函数。非抽象派生类的复制构造函数应调用此受保护的复制构造函数。有了这个,克隆成员函数就像new DerivedClass (*this)
:
class Figure {
private:
virtual double varea()=0;
double multiplier;
protected:
Figure () : multiplier(1.0) {}
Figure (const Figure& src) : multiplier(src.multiplier) {}
public:
virtual Figure* clone()=0;
double area() { return varea()*multiplier; }
};
class Square: public Figure {
private:
virtual double varea() {return L*L;}
double L;
public:
Square(const Square & src) : Figure(src), L(src.L) {}
virtual Figure* clone() {return new Square(*this);}
};
注意:
Square::varea()
设为私有,因为它是在Figure
课程中声明的方式。在派生类中公开父类的私有方法通常有点可疑。multiplier
。答案 1 :(得分:1)
继承与复制语义笨拙地连接。但是,一个解决方案可以让复制构造函数完成工作:
struct Base
{
public:
Base()=default;
virtual ~Base()=default;
virtual Base* clone()=0;
Base& operator=(Base const &) = delete;
Base(Base&&)=delete;
protected:
Base(Base const&) = default;
};
struct Derivated : Base
{
public:
Derivated()=default;
virtual Derivated * clone()
{
return new Derivated (*this);
}
protected:
Derivated(Derivated const&) = default;
};
答案 2 :(得分:0)
为图类添加受保护的访问者:
protected:
double getMultiplier() { return multiplier; }
void setMultiplier(double newValue) { multiplier = newValue; }
虽然您无法直接访问该成员,但您可以访问该乘数。