继承:
- 在子类对象构造时,需要先调用父类的构造函数对继承自父类的成员进行初始化。
- 在子类对象析构时,需要最后调用父类的析构函数对继承自父类的成员进行清理。
- 如果子类中的成员变量和父类中的重名,就用域作用符,父类名::变量名,来对父类中的同名成员变量进行访问。
多态:为了能够对不同的继承类型,调用其下作用不同的同名函数,因此引入了多态的概念。
- 根据(父类)指针指向的实际的对象类型来判断重写函数的调用。
- 如果父类指针指向父类对象,则调用父类中定义的虚函数。
- 如果父类指针指向子类对象,则调用子类中定义的虚函数。
- 利用多态可以实现面向未来的开发。
间接赋值成立的三个条件:
- 函数参数中有一个形参,调用函数前定义一个实参。
- 建立关联:实参取地址传给形参。
- *p(形参,实参的地址),来间接修改实参的值。
重写和重载:
-
下面的基类和子类中的fun函数之间是什么关系?
-
#include<cstdlib> #include<iostream> using namespace std; class Parent01 { public: Parent01(); ~Parent01(); public: virtual void Virtual() { cout << "Parent01类的虚函数:Virtual()" << endl; } void fun() { cout << "Parent01类的无参函数fun" << endl; } void fun(int i) { cout << "Parent01类的有参函数fun" << endl; } virtual void fun(int i, int j) { cout << "Parent01类的虚函数:void func(int i, int j)" << endl; } }; Parent01::Parent01() { cout << "Parent01类的构造函数" << endl; } Parent01::~Parent01() { cout << "Parent01类的析构函数" << endl; } class Children01:public Parent01 { public: Children01(); ~Children01(); void fun(int i,int j) { cout << "Children01类的虚函数fun(int i,int j)" << endl; } void fun(int i,int j,int k) { cout << "Children01的函数void fun(int i,int j,int k)" << endl; } private: }; Children01::Children01() { cout << "Children01类的构造函数" << endl; } Children01::~Children01() { cout << "Children01类的析构函数" << endl; } void run01(Parent01* parent) { parent->fun(0, 1); //parent->Virtual(); } void main01() { Children01 child; run01(&child); //child.Parent01::fun(); Parent01 parent; run01(&parent); parent.fun(1, 2); child.fun(1, 2); child.Parent01::fun(1,2); } void main_001() { main01(); system("pause"); }
-
在使用子类对象,直接调用父类的无参fun()时,会报错,这是因为子类中没有重载函数接受0个参数。
-
这时需要在fun()之前加上基类的域作用符,即采用child.Parent::fun()的形式才能调用。
-
在父类中,定义其他的函数,进行调用是没有问题的。
-
两个参数的虚函是virtual void fun(int i, int j),在子类与父类中的多态是正常工作的。
-
想在子类中直接直接调用无参的fun(),而不报错。要在子类中对fun()进行重定义。
- 在同一个类(作用域、命名空间)内,定义多个函数名相同,形参不同的函数,是函数重载。
-
在不同类之间,定义同名、形参个数相同的函数,是函数重写。上边对无参fun()在基类和父类中的重写就是这个原理。
-
所以子类对象中的fun()和父类对象的fun()发生了名称覆盖。调用自己重写的的fun()和继承自父类的fun()都可以。
-
函数的重写与重载:
子类与父类中,不加virtual关键字的函数重写,叫做重定义。
-
函数重载:必须在同一个类中进行;子类无法重载父类中的函数,只能进行重定义,才能直接用子类对象(对自己定义好的该函数)进行调用,父类同名函数将被覆盖;重载是在类内进行的,是在编译期间,根据重载函数的参数个数和参数类型进行函数调用。
-
函数重写:分为重写和重定义。重写发生在父类与子类之间,并且父类和子类中的函数具有完全相同的函数原型;使用virtual声明的函数重写,会在父类指针调用时,根据指针指向的实际对象的类型,形成多态特性;如果不加virtual,叫作重定义。
-
所以上边两参数的virtual void fun(int i, int j);即使函数重写,又是多态。
-
父类中(类内),加不加virtual的各个func之间仍然是重载关系。
函数重载:函数名相同,参数的个数和类型不同。不包含返回值。
而且virtual是关键字,不是返回值。