一.函数重写
*: 在子类中定义与父类中原型相同的函数
*: 函数重写只发生在父类与子类之间
class Parent
{
public:
void print()
{
cout<<"parent"<<endl;
}
};
class Child:public Parent
{
public:
void print()
{
cout<<"child"<<endl;
}
};
说明: print() 就为重写函数
*: 父类中被重写的函数依然会继承给子类
*: 默认情况下子类重写的函数将隐藏父类中的函数
*:通过作用域分辨符::可以访问到父类中被隐藏的函数
child.print();
child.Parent::print();
void run()
{
Child child;
Parent* pp = &child;
Parent& rp =child;
child.print();
pp->print();
rp.print();
}
问题所在:
(1) C++与C相同,是静态编译型语言
(2) 在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象
(3) 所以编译器认为父类指针指向的是父类对象
(4) 由于程序没有运行,所以不可能知道父类指针指向的具体是父类对象还是子类对象
(5) 从程序安全的角度,编译器假设父类指针只指向父类对象,因此编译的结果为调用父类的成员函数。
void func(Parent* p)
{
p->print();
}
分析: 在编译这个函数的时候,编译器不可能知道指针P指向什么,但是没有理由报错,于是编译器认为
最安全的做法是编译到父类的print函数。
二. 多态的本质
根据实际的对象类型决定函数调用语句的具体调用目标
*: 如果父类指针指向的是父类对象,则调用父类中定义的函数
*: 如果父类指针指向的是子类对象,则调用子类中定义的重写函数
多态: 同样的调用语句有多种不同的表现形态
C++中的多态支持
*: C++中通过 virtual 关键字对多态进行支持
*: 使用virtual声明的函数被重写后即可表现出多态性
父类函数中加入virtual
class Parent
{
public:
virtual void print()
{
cout<<"parent"<<endl;
}
};
小结:
(1) 函数重写只可能发生在父类与子类之间
(2) virtual 关键字是C++中支持多态的唯一方式
(3) 被重写的虚函数即可表现出多态性