#include <iostream>
using namespace std;
class Shape
{
public:
virtual void draw()=0;
};
class Circle:public Shape
{
public:
void draw(){cout<<"circle "<<endl;}
};
class Rectangle:public Shape
{
public:
void draw(){cout<<"Rectangle "<<endl;}
};
我想创建一个图片类,我可以画不同的形状。我正在传递形状类指针(抽象)在图片类的构造函数,像这样:
class Picture
{
public:
Shape* s1;
Picture(Shape *fp): s1(new Shape){}
void PictureDrawn()
{
s1->draw();
}
};
int main()
{
Circle cir;
Picture pic(cir);
pic.PictureDrawn();
}
我得到编译错误。请任何人解释如何正确地编写图片类构造函数,以便我可以制作不同的形状??由于
你不能这么做
new Shape
这是一个实例化抽象类的尝试。我认为你应该做的是:
Picture(Shape *fp): s1(fp){}
这将把参数赋值给变量s1,我认为这是你想要的。
还要注意,底部的代码也不正确。您已经将Picture构造函数声明为接受指向Shape的指针,但随后您将按值传入Circle。你想要的是。
Circle cir;
Picture pic(&cir);
或者,更改Picture类,使其使用引用而不是指针。
class Picture
{
public:
Shape* s1;
Picture(Shape *fp): s1(fp){}
void PictureDrawn()
{
if(s1 != NULL)
s1->draw();
}
};
int main()
{
Circle cir;
Picture pic(&cir);
pic.PictureDrawn();
}
如果我理解正确的话,你的抽象类形状是一个接口,因为它的所有方法都是纯虚拟的。话虽如此,您不能实例化接口。您必须"声明"非虚纯方法或传递指向类的指针。
如果你想复制动态分配的形状,让它可克隆(→常见问题链接)。
这意味着,增加一个方法virtual Shape* clone() const = 0
。
在Shape
派生的每个具体类中实现它。
自动化实现clone
最实用的方法是IMHO定义一个宏。
但是,由于年轻读者对任何定义宏的建议都有不良反应的历史,让我补充一下,在c++ 11中,另一种选择是为clone
实现使用奇怪的循环模板模式(因为c++ 11支持参数转发),而在c++ 98中还有另一种,但相当复杂!,可选的,基于继承层次结构中的支配地位。
然而,说了这么多,让我再次建议使用宏,或者只是在每个类中编写相同的实现(没有名称变化)。