C++中列表的多态性
Polymorphism in lists in C++
我正在用OpenGL和C++编程一个基本的图形场景编辑器,这是上下文:
-
我有一个Drawable类,它是抽象的,只有一个纯虚拟函数draw()。我像使用java接口一样使用这个类。
-
许多继承自Drawable和reimplement-draw()的类。
-
Scene类,其中包含指向Drawables的指针列表。
-
我创建差异的main.cpp Drawable对象并将它们添加到列表中。
我遇到了以下问题:
-
main.cpp中创建的对象不断超出范围,因此创建它们并用引用的对象执行添加函数并不容易。(只是一直保留一个没有有效指针的列表)。
-
苦乐参半的解决方案是用new创建这些新对象,并让Scene类在列表被破坏时删除列表中的指针,或者以某种方式在main.cpp中删除它们。
我真的不喜欢这样,所以我想问是否有一些方法可以复制add函数中的对象,然后将副本存储在列表中,这不是问题,因为复制的对象很快就会被删除。在这个函数中,我不知道我在处理Drawable的哪个子类。我不能直接复制Drawable对象,因为Drawable是一个抽象类,不能用new来制作Drawable对象。只想有一个包含不同对象的列表,所有对象都可以执行draw()。我留下一些代码以防万一:
class Drawable {
public:
virtual void draw() = 0;
virtual ~Drawable() = 0 {}
};
class Figure : public Drawable {
private:
list<Point, allocator<Point>> _points;
int _type;
public:
...
void draw() {
...
}
};
class Scene : public Drawable {
private:
list<Drawable*, allocator<Drawable*>> _drawables;
...
public:
...
void add(Drawable* drawable) {
_drawables.push_back(drawable);
}
~Scene() {
for(iterDrawable it = _drawables.begin(); it != _drawables.end(); ++it)
delete (*it);
}
void draw() {
for(iterDrawable it = _drawables.begin(); it != _drawables.end(); ++it)
(*it)->draw();
}
};
main.cpp
...
void display() {
...
Figure* square = new Figure(GL_POLYGON);
square->add(Point(xSquare, ySquare));
square->add(Point(xSquare + squareWidth, ySquare));
square->add(Point(xSquare + squareWidth, ySquare + squareHeight));
square->add(Point(xSquare, ySquare + squareHeight));
cScene.add(square);
cScene.draw();
...
}
...
我希望我能充分解释。
您想要使用的是一个boost ptr容器:
boost::ptr_list<Drawable> drawlables;
/// STUFF
drawlables.add(new Square);
boost-ptr容器(相对于智能指针容器)的优点在于,容器使对元素的访问看起来像对象(而不是指针)。这使得将它们与标准算法一起使用变得微不足道。
ptr容器拥有插入容器中的任何指针的所有权,因此涵盖了内存管理。所有其他位置都应该传递一个来自容器的引用。
drawlables[0].draw();
// or drawl all of them
for_each(drawlables.begin(), drawlables.end(), std::mem_fun(&drawlables::draw));
Drawable
必须有一个虚拟析构函数- 您必须有某种对象所有权策略。换句话说,对于您分配的每一个对象,您必须对处理该对象有一个非常清晰的想法。与Java不同,C++就是这样做的。分配对象以添加到场景时,场景对象是否会成为组件的最终所有者?如果是,则场景必须在其自身消失之前(即在析构函数中)
delete
其组件的列表。如果场景对象不是所有者,而只是用户,那么谁是所有者?你能保证所有者的寿命比所有用户都长吗?如果没有,所有者将如何将所有权传递给下一个所有者?如果要复制对象,则必须为原始和副本决定此问题 - 像
shared_ptr
和ptr_list
这样新奇的东西很不错,但我建议先学习基础知识。重要的是要了解为什么需要shared_ptr
和ptr_list
,它们声称要解决哪些问题,以及它们的解决方案在30000英尺外是什么样子。获得这种理解的最好方法是偶然发现并试图解决其中的一些问题 Drawable
必须有一个虚拟析构函数- 如果你想以多态的方式复制对象,那么你需要一个多态函数来进行复制。您必须为每个派生类自己编写一个,就像为每个派生类别编写
draw()
一样。这种函数的常用名称是clone
。对于每个类Foo
,clone
将如下所示:virtual Foo* clone() {
nbsp;return new Foo(*this);
}
所有类的clone
版本看起来几乎相同,但您必须手动编写其中的每一个。请注意,这是使用Foo
的复制构造函数,如果Foo
拥有任何其他对象,或者有一个在其他方面不重要的复制操作,则必须自己编写该构造函数 - 我有没有提到
Drawable
必须有一个虚拟析构函数
相关文章:
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 在 C++ 中在堆栈上创建实例时如何保持多态性?
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++ 多态性在代码::块 17.12 中不起作用
- C++ 泛型和多态性:这种模式可行吗?
- 为什么我们实际上需要运行时多态性?
- 如何在这个简单的最小示例中实现多态性?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 无法初始化已知大小的矢量指针,该大小不会因多态性而更改
- 如何使用多态性填充链接列表
- C++中列表的多态性
- C++链表/多态性未运行列表函数
- 带有列表的c++多态性问题
- c++多态性和列表