父类指针、子类指针指向子类对象的问题
C++动态绑定和静态绑定,感觉这文章写的很好
🐳如果父类指针(pb)调用的是 non-virtual函数
Non-virtual函数都是 静态绑定的,那么通过pb(point-to-B)调用的 non-virtual函数永远是在class B中定义的版本,即使pb指向的是派生类对象
#include <iostream>
using namespace std;
class B
{
public:
void foo() {
cout << "calling B's foo\n";
}
};
class D : public B
{
public:
void foo() {
cout << "calling D's foo\n";
}
};
int main()
{
D objd;
B * pb = &objd;
pb -> foo();
return 0;
}
如果说删掉父类中foo函数呢?答案是会报错而不会调用子类的foo函数
main.cpp:22:11: error: no member named 'foo' in 'B' pb -> foo(); ~~ ^
🐣子类指针调用
子类指针一般是不会指向父类的对象的,我也就不考虑了。
子类指针指向子类的对象也就没什么好说的,相当于直接对象使用自己的函数
🐱父类、子类指针调用的是virtual 函数
D objd : 子类对象
#include <iostream>
using namespace std;
class B
{
public:
virtual void foo() {
cout << "calling B's foo\n";
}
};
class D : public B
{
public:
virtual void foo() {
cout << "calling D's foo\n";
}
};
int main()
{
D objd;
B * pb = &objd;
pb -> foo();
D * pd = &objd;
pd -> foo();
return 0;
}
不论是pb还是pd指向子类的对象,调用虚函数foo都会调用D::foo ,因为pb和pd指向的都是一个类型为D的对象
因此:不要重新定义继承而来的non-virtual函数,因为调用非虚函数的时候使用的是静态绑定(由指针的类型决定而不是对象),具体的使用子类的还是父类定义的non-virtual函数取决于指向对象的指针的类型 ,如果父类指针调用子类函数其实执行的是父类的non-virtual函数
新🌰 样例来源
#include <iostream>
using namespace std;
class A
{
public:
virtual void foo()
{
cout << "A's foo()" << endl;
bar();
}
virtual void bar()
{
cout << "A's bar()" << endl;
}
};
class B: public A
{
public:
void foo()
{
cout << "B's foo()" << endl;
A::foo();
}
void bar()
{
cout << "B's bar()" << endl;
}
};
int main()
{
B bobj;
A *aptr = &bobj;
aptr->foo();
A aobj = *aptr;
aobj.foo();
}
B's foo()
A's foo()
B's bar()
在foo函数中,调用了bar()函数,其实真正的应该是this -> bar(),我们的对象其实是B类型的,因此调用的是B的bar
A's foo()
A's bar()
|