父类指针指向子类对象
基类中没有定义虚函数时
1.如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数
2.如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)
3.如果基础类和衍生类定义了相同名称的成员函数,那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定。
但是虚拟函数就是为了对“如果你以一个基础类指针指向一个衍生类对象,那么通过该指针,你只能访问基础类定义的成员函数”这条规则反其道而行之的设计。
当基类中定义虚函数时
当存在虚函数时,调用的函数(前提是他在基类中被声明为虚)将根据指针指向的对象的类型确定。
举例如下:
class A
{
public:
virtual void fa(){ cout << "fa" << endl;}
void fa2(){ cout << "fa2" << endl;}};
class B :public A
{
public:
void fa(){ cout << "fb" << endl;}
void fa2(){ cout << "fb2" << endl;}};
class C :public B
{
public:
void fa(){ cout << "fc" << endl; }
void fa2(){ cout << "fc2" << endl;}};
int main()
{
A *ptr = new C;
ptr->fa();
ptr->fa2();
delete ptr;
return 0;
}
在基类A中函数fa为虚,实际上在派生类B、C中,fa一直是一个虚函数,只是“virtual”被省略掉了,fa2不为虚;因此当A类指针ptr指向C类对象时,ptr->fa()将调用实际指向的对象类型C的fa函数,即输出fc;ptr->fa2()将调用指针的原型,即类型A的fa函数,即输出fa2;
注:若类C中没有定义fa函数,则ptr->fa(),将调用类型B的fa函数,即输出fb。
若改为以下代码:
#include <iostream>
using namespace std;
class A
{
public:
virtual void fa()
{
cout << "fa" << endl;
fa2();
}
virtual void fa2()
{
cout << "fa2" << endl;
}
};
class B :public A
{
public:
void fa()
{
cout << "fb" << endl;
fa2();
}
void fa2()
{
cout << "fb2" << endl;
}
};
class C :public B
{
public:
/*void fa()
{
cout << "fc" << endl;
fa2();
}*/
void fa2()
{
cout << "fc2" << endl;
}
};
int main()
{
A *ptr = new C;
ptr->fa();
ptr->fa2();
delete ptr;
return 0;
}
1)ptr->fa();将调用ptr实际指向的对象类型C的fa,但C没有定义fa函数,故调用函数B的fa函数,输出fb,然后调用fa2函数,虽然此时this指针属于类B,但由于fa2函数为虚函数,将调用ptr实际指向的对象类型C的fa2函数,输出fc2
2)若fa2函数在基类中没有声明为虚,则ptr->fa();将调用ptr实际指向的对象类型C的fa,但C没有定义fa函数,故调用函数B的fa函数,输出fb,然后调用fa2函数, this指针属于类B,调用B的fa2函数,输出fb2.
3)若fa2函数在基类中没有声明为虚,而在C中声明为虚,则仍为2)中的结果。
转载请标注来源