首页 > 解决方案 > 声明一个基类类型的指针,然后通过指向一个子类来实例化它。这是良好的编程习惯吗?

问题描述

我试图弄清楚多态性和指针,并正在关注一些精彩的视频来解释它(如果你真的关心,超链接

他声明class Aclass B从 A 继承。

但是要实例化 B 的对象,他这样做是这样的:

A* b = new B;

它工作正常(他在创建更复杂的类时继续使用该方法,一个基本类型为 Shape 的向量数组,其中包含子类 Square、Circle 等。即

std::vector<Shape*> shapes;
shapes.push_back(new Circle.........
shapes.push_back(new Rectangle.......

有可能,但是声明一个指向基类对象的指针,然后通过指向它的子类来实例化它是否完全可以(甚至推荐)?

我想我刚刚回答了我自己的问题,好处来自能够通过父类引用它们来管理不同对象的集合?那是对的吗?

谢谢!

标签: c++polymorphism

解决方案


但是声明一个指向基类对象的指针,然后通过指向它的子类来实例化它是否完全可以(甚至推荐)?

当你使用

A* ptr = new B();

代替

B* ptr = new B();

您只丢失了少量信息。您不能使用在 中定义B但未在中定义的任何成员函数A。请注意,使用在 中声明但在 中实现的virtual成员函数是完全可以的。AB

如果在您的用例中少量的损失是可以接受的,那么使用A* ptr =. 如果您希望能够保留B指针的 -ness 以便您可以使用它来访问特定于 的成员,则B有必要使用B* ptr =.


关于使用指针/引用类型有一个指导原则:

  1. 在定义函数接口时,使用类层次结构中尽可能高的指针/引用类型来实现函数。

    给定

    struct Shape { ... };
    struct Circle : Shape { ... };
    

    如果Circle函数中需要的所有内容都可以从Shape.

    当您添加 的下一个子类时Shape

    struct Rectangle : Shape { ... };
    

    该功能也可以与 a 一起使用Rectangle而无需任何更改。

  2. 定义指针/引用时,请使用尽可能多地保留信息的类型。

    如果有功能

    Circle* someFunction();
    

    然后,使用

    Circle* circlePtr = someFunction();
    

    代替

    Shape* shapePtr = someFunction();
    

    你可以circlePtr在任何你需要的地方使用 aShape*但你将无法在shapePtr任何你需要 a 的地方使用Circle*


推荐阅读