c++ - 声明一个基类类型的指针,然后通过指向一个子类来实例化它。这是良好的编程习惯吗?
问题描述
我试图弄清楚多态性和指针,并正在关注一些精彩的视频来解释它(如果你真的关心,超链接)
他声明class A
并class B
从 A 继承。
但是要实例化 B 的对象,他这样做是这样的:
A* b = new B;
它工作正常(他在创建更复杂的类时继续使用该方法,一个基本类型为 Shape 的向量数组,其中包含子类 Square、Circle 等。即
std::vector<Shape*> shapes;
shapes.push_back(new Circle.........
shapes.push_back(new Rectangle.......
有可能,但是声明一个指向基类对象的指针,然后通过指向它的子类来实例化它是否完全可以(甚至推荐)?
我想我刚刚回答了我自己的问题,好处来自能够通过父类引用它们来管理不同对象的集合?那是对的吗?
谢谢!
解决方案
但是声明一个指向基类对象的指针,然后通过指向它的子类来实例化它是否完全可以(甚至推荐)?
当你使用
A* ptr = new B();
代替
B* ptr = new B();
您只丢失了少量信息。您不能使用在 中定义B
但未在中定义的任何成员函数A
。请注意,使用在 中声明但在 中实现的virtual
成员函数是完全可以的。A
B
如果在您的用例中少量的损失是可以接受的,那么使用A* ptr =
. 如果您希望能够保留B
指针的 -ness 以便您可以使用它来访问特定于 的成员,则B
有必要使用B* ptr =
.
关于使用指针/引用类型有一个指导原则:
在定义函数接口时,使用类层次结构中尽可能高的指针/引用类型来实现函数。
给定
struct Shape { ... }; struct Circle : Shape { ... };
如果
Circle
函数中需要的所有内容都可以从Shape
.当您添加 的下一个子类时
Shape
,struct Rectangle : Shape { ... };
该功能也可以与 a 一起使用
Rectangle
而无需任何更改。定义指针/引用时,请使用尽可能多地保留信息的类型。
如果有功能
Circle* someFunction();
然后,使用
Circle* circlePtr = someFunction();
代替
Shape* shapePtr = someFunction();
你可以
circlePtr
在任何你需要的地方使用 aShape*
但你将无法在shapePtr
任何你需要 a 的地方使用Circle*
。
推荐阅读
- node.js - 如何使用 Puppeteer 遍历具有相同类的 div
- sql-server - Azure SQL - 将 ****** 值“******”转换为数据类型 ****** 失败
- javascript - 打破'滚动'事件Javascript
- python - 如何使用 pandas 从 Azure Blob 读取 .xlsx 格式文件而不创建临时文件
- python - 为什么 Pytorch 给我一个数据类型错误:Float vs Double?
- linux - 如何保护 ClamAV 守护进程和客户端之间的通信?
- python - 使用 Python 和 Scapy 计算 SYN 和 ACK 数据包的数量
- android - Flutter - 在 MIUI 11.0.1 上没有播放 Flutter 本地通知声音?
- javascript - 正则表达式 - 在最后一个连字符/破折号之前提取文本
- php - 如何将多个类添加到 the_post_pagination 数组?