我在课堂上学习c++,我正在努力尝试使用虚拟创建/克隆函数返回一个指向派生对象的指针。
我找到了这个实现,并打算围绕它构建http://www.cs.uregina.ca/Links/class-info/210/C++FAQ/virtual-functions.html#[20.5]
我不明白的是,在clone()或create()退出它们的块之后,返回的指针实际上是如何指向任何相关数据的?
是否有更好的方法来做到这一点,或者这是我需要在每个情况下编程一个函数?
谢谢
class Shape {
public:
virtual ~Shape() { } // A virtual destructor
virtual void draw() = 0; // A pure virtual function
virtual void move() = 0;
// ...
virtual Shape* clone() const = 0; // Uses the copy constructor
virtual Shape* create() const = 0; // Uses the default constructor
};
class Circle : public Shape {
public:
Circle* clone() const { return new Circle(*this); }
Circle* create() const { return new Circle(); }
// ...
};
…在clone()或create()退出它们的块之后,返回的指针实际上是如何指向任何相关数据的?
操作符new
动态分配内存。该内存在使用delete
释放之前是有效的。clone()
和create()
都没有"删除"这些指针,所以这两个函数都返回一个有效的指针。
是否有更好的方法来做到这一点,或者这是我需要在每个情况下编程一个函数?
由于这里使用了多态性,因此假设用户使用Shape
类并且不知道这些对象的实际实现(即他们只使用"接口")。如果不知道实际的实现是什么,就不可能创建或复制对象。
唯一知道类型的地方是实现接口的类的方法内部(在您的例子中是Circle
)。因此,只有在这里,您才能基本了解类型,大小以及创建和/或复制对象所需的所有其他必要信息。所以答案基本上是肯定的,您必须为继承Shape
的每个顶级类实现create()
和clone()
。否则,要么无法创建/克隆对象,要么更糟——你可能会遇到对象切片问题。
创建一个静态对象是一个可行的解决方案,还是否定所有的工作是面向对象?
我不明白创建静态对象在这里有什么帮助。静态对象通常在每个作用域存在一个实例。使用create()
和clone()
的全部目的是能够创建对象的多个实例(默认实例或现有实例之一的副本)。因此,拥有单个静态实例将无助于实现代码应该做的事情。
Clone()的用法与通常完全相同。Create()不是真的。您能展示一个通过虚拟调度使用它的用例吗?
我经常使用的是静态成员Create()。那是工厂的方法。每个类都在映射中注册,带有一些ID和指向Create函数的指针。然后可以用来创建只知道ID的适当对象(比如从文件中读取),然后在新实例上调用虚函数(即从文件中反序列化内容)。为了避免复制粘贴,我使用了一个宏来声明和实现所有的强制函数。