我有下面的代码,其中有一个基类和一个派生类。基类和派生类都具有共享相同名称的函数成员。在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;
}
答案 0 :(得分:1)
在您的特定情况下,调用b完全正常。
您有一个指向Derived类的指针,它不是虚拟的。因此,编译器将生成对Derived :: b方法的调用。
现在,当执行b时,将废话放入this指针时,这是未定义的行为。 但是在您的情况下,因为您不访问this指针,所以没有问题。
答案 1 :(得分:0)
将基类转换为派生类会导致未定义的行为
答案 2 :(得分:0)
据我所知,该函数不会占用内存中的任何额外空间,它像普通函数一样存储。您可以将成员函数视为普通函数,并带有一个额外的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在内存中没有任何成员。