这个问题在这里已有答案:
我有下面的代码片段,我有一个基类和派生类。基类和派生类都具有共享相同名称的函数成员。在main()中,我将一个基类对象类型化为派生类指针并尝试调用该函数。令我惊讶的是,它正在调用派生类函数成员。据我所知,基类对象将没有任何有关派生类对象的信息。那么,为什么我的派生类指针仍然能够访问派生成员函数?
在向上转换的情况下,我理解派生类对象将具有基类的内容,这就是指向派生类对象的基类指针将按预期工作的原因。
有人可以帮助我理解如何在这里调用派生类成员函数,即使我有一个派生类指针指向一个基类对象(没有派生类的信息)?
#include<iostream>
using namespace std;
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
public:
void b()
{
cout << "derived";
}
};
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
d1->b();
return 0;
}
在您的具体情况下,调用b是完全正常的。
你有一个指向Derived类的指针,它不是虚拟的。因此编译器将生成对Derived :: b方法的调用。
现在,当b执行时,当你在这个指针中放入垃圾时,它是未定义的行为。但在你的情况下,因为你没有访问这个指针,所以没有问题。
将基类转换为派生类结果未定义的行为
据我所知,该函数不占用内存中的任何额外空间,它像普通函数一样存储。您可以使用额外的this指针将成员函数视为普通函数。通常,要调用的函数由对象指针的类型决定。但虚函数不同,它由虚函数表调用,在你的代码中,没有声明的虚函数。所以没有虚函数表。
您可以以不同的方式查看代码:
void derived_b(derived* this)
{
cout << "derived";
}
void base_b(base* this)
{
cout << "base";
}
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
derived_b(d1);
return 0;
}
如果在类中定义某个成员,并在函数b中使用它,则可能会导致一些错误
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
int a;
public:
derived(){a = 1;}
void b()
{
cout << "derived" << a;
}
};
main()中的代码可能会导致错误,因为对象b在内存中没有任何成员。