我正在制作一个油漆程序。程序将按照绘制的顺序存储在图形窗口上绘制的元素。我想使用" LIST"存储绘制的形状。形状具有不同的类型,即allShapes是父类,line是子类。请告诉我如何在allShapes列表中存储一行并调用它的功能。
以下是示例代码:
class allShapes
{
protected:
int * points; //vertices of the shape
int color; //color of the shape
int n; //no. of points
public:
//virtual void draw()= 0;
virtual void draw()
{
}
};
class line:public allShapes
{
public:
line()
{
points = new int[4];
n = 2;
}
void draw()
{
//Code here
}
};
int main()
{
int mouse_x, mouse_y;
char key_pressed;
GP142_open(); /* Open and initialize the GP142 Graphics Window */
list<allShapes> shapes;
int quit = 0;
while (!quit) {
switch (GP142_await_event(&mouse_x, &mouse_y, &key_pressed)) {
case GP142_MOUSE:
if ((mouse_x > -490 && mouse_x<-445) && (mouse_y>305 && mouse_y < 360)) // If user selects the draw line option
{
line newLine;
shapes.push_back(newLine);
allShapes check = shapes.front();
check.draw();
}
break;
case GP142_QUIT:
quit = 1;
break;
default:
break;
}
}
}
但程序不会调用line对象的draw函数。我在allShapes中也有虚拟函数绘制。如何调用check.draw()在屏幕上画一条线?
答案 0 :(得分:1)
对于多态对象,您无法为基类保留足够的存储空间,然后期望能够将任何派生类阻塞到该空间中。当你说:
时,你就是这么做的list<allShapes> shapes;
每当您尝试将line
卡入allShapes
对象的空间时,将会发生allShapes
line
部分的存储, line
部分将被忽略。那么你有一个不是line
的对象,并且在其上调用.draw()
将不会调用line::draw()
。在给定对象的动态类型draw()
的情况下,它将调用正确的allShapes
方法。
当你说:
时,同样的事情再次发生allShapes check = shapes.front();
check.draw();
shapes.front()
的任何类型结果都会转换为allShapes
。如果您有一个line
的列表,那么它将在此处转换为allShapes
。
使用多态通常需要使用指针或引用:
list<unique_ptr<allShapes>> shapes;
现在您可以将行放入此集合中:
shapes.push_back(make_unique<line>()); // make_unique is C++14
这样line
不会转换为allShapes
,所以当完成虚拟调度以根据对象的真实动态类型找到正确的方法时,draw()
方法将使用line
。
要访问列表中的对象,您可以使用引用:
allShapes &check = shapes.front();
check->draw();
如果您使用默认使用引用类型的语言(例如Java或C#)来使用C ++,那么您真的需要了解C ++值类型的工作原理。在其他语言中,您可以在所有地方使用指针,但语法并没有那么明显。要在C ++中使用指针,必须显式使用特殊的指针语法。
您可能会找到另一个答案,其中我介绍了这个有用的内容:Confused with object arrays in C++
答案 1 :(得分:0)
问题在于:
line newLine;
shapes.push_back(newLine);
allShapes check = shapes.front();
check.draw();
您复制线对象,而非引用。
容器shapes
不应由对象组成,而应由指针组成。
如果将线对象复制到allShapes
对象中,allShapes
对象将不会变为line
。
将容器声明为
list<allShapes*> shapes;
然后写
line* newLine = new line();
shapes.push_back(newLine);
allShapes* check = shapes.front();
check->draw();
并记住某处的delete
对象。