基类的C++数组,该数组的元素中存储有派生类的实例
C++ array of base class which has instances of derived classes stored in the elements of the array
我正在创建一个应用程序,该应用程序允许用户定义不同形状的尺寸,并使用用户指定的尺寸将区域返回给用户。
我的基类是Shape。派生类有三角形、圆形、正方形和矩形。
我创建了一个Shape数组,希望在运行时创建并存储数组中任何派生类的实例。
Shape** shape = new Shape*[TOTAL_SHAPES];
shape[i] = new Circle(radius);
我已经做到了,但是我无法访问实例化的类方法。很抱歉,如果这是一个愚蠢的问题,我对C++还很陌生。
让我们假设您的类型具有以下定义
class Shape {
public:
void Method1() { ... }
};
class Circle : public Shape {
void Method2() { ... }
}
有了这个定义,您可以通过执行以下来访问Shape
上的方法
shape[i]->Method1();
然而,在这种情况下,不可能访问Method2
,因为编译器只知道Shape
,而不知道Circle
。
shape[i]->Method2(); // Error!
您有三个选项:
- 将
Shape
设为抽象基类,并调用作为Shape
成员的virtual
方法 - 使用
static_cast
从Shape*
强制转换为Circle*
,并通过它调用方法 - 使用
dynamic_cast
从Shape*
强制转换为Circle*
,并通过它调用方法
在许多情况下,第一个选项可能是最好的。除其他原因外,你几乎肯定需要一个virtual
析构函数(这可能是使Shape
成为ABC的副产品),而且你可能不想知道指向的对象是什么类型,而是想简单地调用它可能是什么的方法。如果你能用这个习惯用法,就用它吧。
第二种选择是危险的。您必须绝对知道要指向的对象是Circle
(或其他任何对象)才能使用static_cast
,否则您将得到Undefined Behavior。
第三个选项只有当您的类是多态时才可用,这意味着Shape
必须至少有一个virtual
方法。你当然应该有一个virtual
析构函数,这将达到这个目的。
怎么样:
shape[i]->aMethod();
对于初学者,我强烈建议使用智能指针包装器,而不是使用原始指针(尤其是如果您是该语言的新手)。
std::vector<std::shared_ptr<Shape>> shapes(TOTAL_SHAPES);
这将定义一个初始大小为TOTAL_SHAPES
的向量。
从根本上讲,您希望使用Shape*
调用的任何方法都必须对Shape
有效,或者您必须进行有风险的向下转换到适当的类型。例如:
class Shape
{
public:
// constructors and other methods go here
virtual ~Shape() { } // virtual destructor
virtual void Draw() { } // virtual function to be used by derived classes
};
class Circle
{
public:
// ...
virtual ~Circle() { }
virtual void Draw() { } // override the virtual function
};
然后,在您的应用程序代码中,
std::vector<std::shared_ptr<Shape>> shapes(TOTAL_SHAPES);
shapes[0] = std::make_shared(new Circle);
shapes[0]->Draw(); // calls Circle::Draw
请注意,根据您的使用情况,std::unique_ptr
可能会取代std::shared_ptr
。
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 如何使用数据成员填充派生类的对象到基类的指针数组中
- std::数组派生类聚合初始化
- 指向不同派生类的指针数组
- 创建指针是否超过非数组指针的末尾,而不是从 C++17 中的一元运算符和未定义的行为派生?
- 从基类数组调用派生函数
- 如何创建一个动态数组,该数组可以保存从C++中派生的同一基类的所有不同对象
- 如何在C 中的派生类中分配数据成员数组
- 在C 中的数组中存储抽象基类的不同派生类的对象
- 使用数组作为对象调用派生类的方法
- 我怎么知道基类对象的指针数组中元素的类型,它将为派生类分配内存
- 如何将基类指针数组强制转换为派生类
- 如何使数组的派生类型接受聚合初始化?
- 指向基类数组的指针,填充派生类
- 在单个指针数组中调用不同派生类的虚拟方法
- 基类的C++数组,该数组的元素中存储有派生类的实例
- 基类和派生类的二维动态数组
- 将派生对象添加到(抽象的)基指针数组中
- 如何对派生模板类C++中的对象数组进行排序
- 矢量强制转换与派生对象到基对象的数组转换