如何创建指向派生类的新指针,该派生类在C++编译时未知

How to create a new pointer to a derived class which type is unknown at compile time in C++?

本文关键字:派生 未知 编译 指针 C++ 创建 何创建 新指针      更新时间:2023-10-16

我有一个代码,其中有一些指向同一基类的派生类的指针。在某一时刻,我需要创建另一个指向此派生类之一的指针,但我不知道在编译时它将指向哪个类。下面是一个代码示例:

#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,但在编译时返回错误:

错误:抽象类类型"多边形"的新表达式无效

如何更正软件?

你要求的是一个虚拟(复制(构造函数,即一个clone()函数。

显然,不能只使用与基类相关的构造来实例化派生类。但是基类指针后面仍然有一个派生类实例,它可以封装构造另一个实例的"能力"。

这个成语被称为虚拟构造函数 - 它甚至不难实现。简而言之,您将拥有一个非静态虚拟方法,该方法在堆上构造一个新实例,并且可以从基类中使用。它将看起来像这样:

Polygon* poly = get_a_poly_which_really_is_some_derived_class();
Polygon* another_poly = poly->create();

笔记:

  • 我刚刚注意到,使用纯虚拟方法克隆C++类基本上是一个克隆,并且具有相似的答案。
  • 除非您真的需要,否则我不建议您这样做。我想除了诉诸虚拟构造对象之外,可能还有更好的选择。
  • 不要使用原始指针,而是使用 std::unique_ptr<Polygon>std::shared_ptr<Polygon>