将指向基对象的指针转换为派生类的指针
converting pointer to base object into pointer of derivate class
我一直对将基类对象的指针转换为派生类的指针感到困惑。 请检查以下代码:
derivate_class *d1 = (derivate_class*)cb;
d1->print();
d1->print1();
结果是:
谁能帮我解释为什么d1->print()
打印"我是基础中的虚拟函数"。
#include <iostream>
using namespace std;
class base
{
public:
virtual void print()
{
cout << "I'm a virtual function in base." << endl;
}
};
class derivate_class : public base
{
public:
void print()
{
cout << "I rewrite the virtual function in base." << endl;
}
void print1()
{
cout << "I'm a function in derivate class." << endl;
}
};
int main()
{
base* b = new base();
derivate_class *d = new derivate_class();
b->print();
d->print1();
base* cb = b;
b = d;
b->print();
cout << "*********************" << endl;
derivate_class *d1 = (derivate_class*)cb;
d1->print();
d1->print1();
system("pause");
return 0;
}
它是 UB,所以任何事情都可能发生。
但这里有一个解释:d1
实际上并不指向derivate_class
,而是指向base
。
base* b = new base();
//...
base* cb = b;
derivate_class *d1 = (derivate_class*)cb;
d1->print();
d1->print1();
调用是动态解析的,因为它是通过指针进行的,并且该方法virtual
。
print1
不会virtual
因此调用是静态解析的。 然而print
是virtual
的,所以最派生类型的实现被调用。但在这种情况下,派生最多的类型实际上是base
。
在引擎盖下,在 vfptr cb
指向的虚函数表中查找方法print
。由于cv
是一个base
,该表将是base
的表,其中包含与base::print
实现print
的函数。这就是调用函数的原因。
d1 是一个derivate_class指针,但它实际指向的数据 (cb) 是 base 类型的。 由于 print() 是虚拟的,因此调用是动态解析的,因此它将在虚拟函数表中找到 base 的实现,而不是derivate_class的实现。
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 如何使用基类指针引用派生类成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 如果基类包含双指针成员,则派生类的构造函数
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 如何在工厂方法中返回指向基于基础操作系统的派生类的有效指针
- 指向基类派生类的 std::unique_ptr 的指针
- 当我在 C++ 中将派生类的指针分配给指针时,地址会更改
- 从基指针到派生的强制转换问题
- 派生类是从基类继承 v 指针并仅使用它,还是也有自己的 v 指针?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 从基类指针派生派生类的模板类型
- 指向从指针派生类成员函数的指针,指向基类成员函数
- 访问通过指针派生的类
- 如果未使用虚拟函数,则使用基类指针派生类的任何目的
- 从基指针C++派生类的类型
- 无法从指针派生类转换为指针基类(多态性)
- C++ - 传递智能指针派生类