为何解引用多态指针得到指针类型而非对象类型?
问题解答
先看你给出的测试代码(补充必要头文件和命名空间以保证可编译):
#include <iostream> using namespace std; class father{ public: father()= default; virtual void func(){ cout << "father" << endl; } }; class child:public father{ public: child() = default; void func(){ cout << "child" << endl; } }; int main(){ father* fptr = new child; auto s = *fptr; //why type of s will be father? (*fptr).func(); //child s.func(); //father return 0; }
第一个疑惑:为什么解引用多态指针后得到的是指针的类型而非实际对象的类型?
这是C++里的**对象切片(Object Slicing)**现象。当你执行auto s = *fptr;时,你并不是把fptr指向的child对象直接赋值给s,而是用*fptr(静态类型为father)拷贝构造了一个新的father类型对象s。这个过程中,child对象里属于派生类的部分会被"切掉",只保留基类father的成员,所以s的类型就是father,和原对象的实际类型无关。
第二个疑惑:既然解引用会消除多态,那为什么(*fptr).func()能正常工作?
解引用fptr得到的结果,静态类型确实是father,但它本质上是指向原child对象的基类左值,而不是一个独立的基类对象。当调用虚函数func()时,C++会根据对象的动态类型(也就是实际指向的child对象)来决定调用哪个版本的函数——这正是多态的核心:虚函数的调用由对象的实际类型决定,而不是静态类型。
而s是一个独立的father对象,它的动态类型和静态类型都是father,所以调用s.func()时自然会执行基类的版本。
内容的提问来源于stack exchange,提问作者Kevin eyeson
相关产品推荐
相关产品推荐

