cpp_polymorphism - ShenYj/ShenYj.github.io GitHub Wiki
-
父类指针可以指向子类对象,是安全的,开发中经常用到(继承方式必须是public)
struct Person { int m_age; }; struct Student: Person { int m_score; }; int main() { /// 父类指针指向子类对象 Person *p = new Student(); getchar(); return 0; }
-
子类指针指向父类对象是不安全的 (结合内存布局,子类的内存范围往往大于父类,父类指针范围小于子类,所以访问内存时相对安全)
Student *p = (Student *)new Person();
-
默认情况下,编译器只会根据指针类型调用对应的函数,不存在多态
-
多态是面向对象非常重要的一个特性
- 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果
- 在运行时,可以识别出真正的对象类型,调用对应子类中的函数
-
多态的要素
- 子类重写父类的成员函数(override) 【函数名、返回值、参数 完全一致,默认是不存在多态的,只看指针类型】
- 父类指针指向子类对象
- 利用父类指针调用重写的成员函数
- C++中的多态通过虚函数(virtual function)来实现
- 虚函数:被virtual修饰的成员函数
- 只要在父类中声明为虚函数,子类中重写的函数也自动变成虚函数(也就是说子类中可以省略virtual关键字)
struct Animal {
virtual void speak() {
cout << "Animal::speak()" << endl;
}
virtual void run() {
cout << "Animal::run()" << endl;
}
};
struct Dog : Animal {
override void speak() {
cout << "Dog::speak()" << endl;
}
override void run() {
cout << "Dog::run()" << endl;
}
};
struct Cat : Animal {
void speak() {
cout << "Cat::speak()" << endl;
}
void run() {
cout << "Cat::run()" << endl;
}
};
void liu(Animal *p) {
p->speak();
p->run();
}
int main() {
liu(new Dog()); /// Dog::speak() Dog::run()
liu(new Cat()); /// Cat::speak() Cat::run()
getchar();
return 0;
}