多态性和类型转换
Polymorphism and type conversion
我对多态性的一个方面感到困惑。请考虑以下代码:
#include <iostream>
class CBase {
virtual void dummy() {}
};
class CDerived: public CBase {
public:
int a,b,c,d;
CDerived (): a(1),b(2),c(3),d(4) { }
};
int main () {
CBase* pba = new CDerived;
std::cout << "sizeof(CBase) = " << sizeof(CBase) << std::endl; // prints 8
std::cout << "sizeof(CDerived) = " << sizeof(CDerived) << std::endl; // prints 24
std::cout << "sizeof(*pba) = " << sizeof(*pba) << std::endl; // prints 8 (?)
return 0;
}
我的问题如下:在CBase* pba = new CDerived;
行上,分配了一个CDerived
类型(24字节)的对象,但正如您所看到的,sizeof(*pba) = 8
字节。pba
指向的CDerived
对象的其他16个字节发生了什么情况?我也试过这个:
std::cout << "pba->a = " << pba->a << std::endl;
但随后出现编译错误,这意味着pba
确实没有指向CDerived
类型的对象。那么这里发生了什么?内存泄漏?
sizeof
是一个编译时构造。它不知道运行时类型,所以只考虑编译时类型,即CBase&
。
pba->a
不编译的原因类似:pba
的编译时类型是CBase*
,而CBase
没有a
成员。这就是静态类型语言的工作方式。如果要使用CDerived
成员,则需要一个类型为CDerived
的变量(或指向它的引用或指针)。
但是,CDerived
对象仍然存在。您可以看到,如果将指针转换为指向CDerived
的指针,就像dynamic_cast<CDerived*>(pba)->a
一样。
sizeof
返回对象的静态类型的大小,由于pba
是CBase*
,因此*pba
的静态类型是CBase
,其大小是8
(没有数据成员和vfptr
)。\
[…]意味着pba真的不指向经过CDerived 类型的对象
确实如此,但您不能通过指向CBase
的指针访问CDerived
特定的成员。
假设我将一个CBase*
交给您,并告诉您访问成员a
。你不能。您不能确定它是指向CDerived
的指针,并且具有该成员,或者指向其他派生类(除非使用RTTI)通过基类指针访问派生类成员在逻辑上是没有意义的。
相关文章:
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 如何调用指针类型的方法(禁用多态性)?
- 使用多态性时在子对象之间进行转换?
- 如何为多态性中的指定类型分配内存
- C 多态性:允许模棱两可的成员类型
- 如何避免使用模板类型的派生类进行多态性动态强制转换
- 自动复制=按值并支持多态性的适当类型的非静态字段
- 具有不同模板类型的子类的多态性
- 多态性并获取C++中的对象类型
- C 模板和多态性无缝合用户定义的转换
- 多态性(继承)和价值类型
- c++多态性:基类的上转换/下转换和容器,缺少数据
- C++技术:类型擦除与纯多态性
- 具有 dynamic_cast 和类型标识的 C++ 多态性
- 多态性和类型转换
- 如何使用基类指针调用派生类非虚拟成员函数,而无需类型转换和使用多态性
- 数据类型和多态性
- c++多态性和类型转换
- C++ 多态性和派生类类型 - "ugly programming"指针类型转换
- 根据"foreign"子类型采取特定操作,不带开关、强制转换等。我们可以以某种方式使用多态性吗?