我知道虚拟类他们无法实例化,现在我对一个案例有疑问,假设我们有一个纯抽象类,如下所示:
class Color{
public:
Color();
virtual string getName()=0;
~Color();
};
和2类继承形式:
class Blue:public Color
{
public:
Blue();
~Blue();
string getName();
};
class Red:public Color{
public:
Red();
~Red();
string getName();
};
和第三类希望使用Color
类作为其构造函数参数和数据成员:
class Foo{
public:
Foo();
Foo(Color&);
~Foo();
void draw(Color&);
private:
Color* co;
};
及其实施:
Foo::Foo():co(new Color()){
}
Foo::Foo(Color &c):co(new Color(c)){
}
现在,我知道此部分new Color()
和new Color(c)
在这种情况下是错误的,但我只希望使用Color
类型传递给Foo
而不是直接使用Blue
或Red
作为参数。
什么是解决方案?我必须使用超载或其他东西吗?对于方法draw
,我有什么问题吗?
我读到了关于设计模式的内容,它对我这个案例有帮助吗?
tnx为您的回复。
答案 0 :(得分:1)
将您的成员指针初始化为nullptr
:
Foo::Foo() : co(nullptr) {}
Foo::Foo(Color &c) : co(nullptr) {}
答案 1 :(得分:1)
对于采用Color&的构造函数,如果可以确定它将继续存在,则可以存储传入颜色的引用或指针,或者智能指针可能适合您的使用存储指向以前存在的颜色的指针,并确保它不会过早删除。或者,如果您希望您的班级拥有自己的颜色副本,您可以使用克隆模式。 颜色的复制构造函数必须返回一种颜色(不是从它派生的类),这是不可能的,因为颜色是抽象的。克隆将是一个返回颜色指针的颜色虚拟函数。在派生类中,它被实现为返回派生类型的新实例。
<table>
<tr >
<td>15</td>
<td>15</td>
<td>30</td>
</tr>
<tr>
<td>45</td>
<td>60</td>
<td>45</td>
</tr>
<tr>
<td>60</td>
<td>90</td>
<td>90</td>
</tr>
</table>
对于默认的foo构造函数,你需要选择foo的color *成员是否为null,如果是,则按照建议传入nullptr。 如果没有,您可以选择默认颜色来初始化颜色*。注意Foo仍然保持颜色*而不是红色*。您可以使用typedef或using语句指定默认颜色类,以确保只定义一次默认颜色: -
class Color
{
public:
virtual Color* Clone() const = 0;
};
class Red : public Color
{
public:
virtual Red* Clone() const
{
return new Red(*this); // updated to use copy constructor
}
};
Foo::Foo(const Color& c) : co(c.Clone())
{}
或者只是不给Foo一个默认构造 - 坚持提供颜色