我有一个代码,其中有一些指向同一基类的派生类的指针。有一次,我需要创建另一个指向这个派生类之一的指针,但我不知道在编译时它将指向哪个类。 这是代码示例:
#include <iostream>
using namespace std;
class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; };
virtual int area() = 0;
};
class Rectangle: public Polygon {
public:
int area()
{ return width*height; }
};
class Triangle: public Polygon {
public:
int area()
{ return width*height/2; }
};
int main () {
Rectangle* rect = new Rectangle;
Triangle* trgl = new Triangle;
Polygon* ppoly;
trgl->set_values (4,5);
ppoly = trgl;
cout << ppoly->area() << '\n';
trgl->set_values (8,5);
cout << ppoly->area() << '\n';
return 0;
}
如上所述编写代码,'ppoly'指向与trgl相同的内存,因此2行cout << ppoly->area() << '\n'
打印不同的结果,因为我更改了指针trgl
的宽度。在我的代码中我不想要这种行为,但我希望ppoly
是同一类型trgl
的新指针。
我曾尝试使用Polygon* ppoly = new Polygon
,但在编译时返回错误:
错误:抽象类类型'Polygon'
的new-expression无效
如何更正软件?
答案 0 :(得分:3)
您要求的是virtual (copy) constructor,即clone()
功能。
答案 1 :(得分:1)
显然,除了基类相关的构造之外,你不能使用任何东西来实例化派生类。但是基类指针仍然有一个派生类实例,它可以封装&#34;能力&#34;构建另一个实例。
这个成语被称为https://kitware.github.io/vtk-js/docs/intro_vtk_as_es6_dependency.html - 它甚至难以实现。简而言之,您将拥有一个非静态虚方法,该方法在堆上构造一个新实例,并且可以从基类中使用。它看起来像:
Polygon* poly = get_a_poly_which_really_is_some_derived_class();
Polygon* another_poly = poly->create();
注意:
std::unique_ptr<Polygon>
。