C++ 具有非虚拟接口和一些私有变量的克隆方法
我有一个抽象类,比如说C++ 具有非虚拟接口和一些私有变量的克隆方法,c++,clone,virtual,member,non-virtual-interface,C++,Clone,Virtual,Member,Non Virtual Interface,我有一个抽象类,比如说Figure,还有一些派生类:Circle,Square 类图实现了: private: virtual double varea()=0; double multiplier; public: virtual Figure * clone()=0; double area() { return varea()*multiplier; } 例如,正方形图形的行为如下: private: double L; public: virtual Figur
Figure
,还有一些派生类:Circle
,Square
类图实现了:
private:
virtual double varea()=0;
double multiplier;
public:
virtual Figure * clone()=0;
double area() { return varea()*multiplier; }
例如,正方形图形的行为如下:
private:
double L;
public:
virtual Figure * clone() {return new Square(*this);}
virtual double varea() {return L*L;}
调用clone方法时,我很难分配变量乘数。实现这一目标的最佳方式是什么?当然,这只是一个愚蠢的例子,有很多变通方法,但实际上,有多个派生级别,它们并不那么明显,所以请坚持这种模式
我是否也应该为方法克隆选择虚拟接口?通过这种方式,我可以直接在Figure类中分配乘数,而无需让每个Figure知道其乘数。向Figure类添加受保护的访问器:
protected:
double getMultiplier() { return multiplier; }
void setMultiplier(double newValue) { multiplier = newValue; }
这样,您就可以访问乘法器,尽管您无法直接访问该成员。除非您为类声明了一个副本构造函数。该语言免费为您提供一个,并且是公共的。您不需要这个免费的公共副本构造函数。这将导致切片。使类的复制构造函数受保护。非抽象派生类的复制构造函数应调用此受保护的复制构造函数。这样,克隆成员函数就简单得像
new-DerivedClass(*this)
:
请注意:
- 我将
设为私有,因为它在类Square::varea()
图中是这样声明的。在派生类中将父类的私有方法公开为公共方法通常有点可疑
- 赋值运算符有问题。这件事由你决定
- 您需要某种方法来设置
乘数
- 继承与复制语义笨拙地连接。但是,一种解决方案是让复制构造函数执行此任务:
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;
};
乘数是私有的,所以您要么需要一个受保护的setter,要么需要一个将乘数作为参数的构造函数。然后子类构造函数可以将乘数值传递给父构造函数。@我希望能够避免编辑所有现有的派生图形,并为我仍然需要编写的图形保留轻型构造函数。没有其他理由让数字看到它们的乘数。我不清楚如何通过这样做来解决问题。在派生的类中,clone方法返回的
派生的*
只是一个输入错误吗?我不太熟悉默认的复制构造函数,它是派生的(派生常量&)=default代码>同时调用Base(Base const&)
?1)谢谢,我的不精确!2) 是的,它必须使用克隆方法。3) 当然!
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;
};