1、如果要在继承中实现多态,子类对父类对继承必须是public。
如下我们同时进行三种继承方式,然后调用:
class Child :Father{ //class Child :protected Father{ //class Child :public Father{
Child child; Father *father = &child;
第一种会报错:
jicheng.cpp:62:20: error: cannot cast 'Child' to its private base class 'Father' Father *father = &child; ^ jicheng.cpp:28:14: note: implicitly declared private here class Child :Father
第二种会报错误:
Father *father = &child; ^ jicheng.cpp:29:14: note: declared protected here class Child :protected Father{ ^~~~~~~~~~~~~~~~ 1 error generated.
只有第三种情况会正常运行
2、继承中父类用virtual与不用virtual的区别:
virtual本质:
virtual是用来定义一个虚函数。虚函数是c++中用于实现多态(polymorphism)的机制。核心理念就是通过积累访问派生类定义的函数。
如果在继承的过程中,父类不用virtual,那么不论指针怎么转换,我们对成员的访问都是通过对象来决定的。
如果我们把父类的成员函数定义成virtual,在访问时就会根据指针类型来决定调用父类还是子类的方法。这是c++中存在virtual的根本意义。
如下事例,如果我们在父类中没有定义virtual:
int func_para1(int a, int b)
Child child; Father *father = &child; father->func_para1(a, a);
运行的结果是:
Father my para is: 5
这里,我们不会去区分这个father指针指向的对象到底是根据哪个类生成的,指针类型是哪个类,我们就到这个类中去找调用方法。
如果我们把函数定义成virtual:
virtual int func_para1(int a, int b) //int func_para1(int a, int b)
运行的结果是:
Child my para is: 5
这里,我们根据具体的对象,成功的找到了子类的方法。
3、重载与覆盖:
传入函数的参数,可以有多种情况。我们会定义多个同名函数,每个函数都有不同的参数传入。这种情况叫重载。
在继承中,如果子类定义了一个父类的同名的函数,那么,父类中全部的同名函数将都被隐藏。这时,我们要想在子类中调用父类中对应的方法,就要全部自己实现。也就是说,我们只要在子类中定义了父类的函数,就意味着我们放弃了父类中全部的重载方法。
如下:如果我们把child class中的方法全部注释掉,然后运行下面的代码是可以的。
Child child; child.func_para1(a, a);
可是,如果在子类中我们把 int func_para1(int a) 这个方法打开,而不放开func_para1(int a , int b)。然后在运行上面的代码,就会提示找不到方法:
jicheng.cpp:70:9: error: too many arguments to function call, expected 1, have 2; did you mean 'Father::func_para1'? child.func_para1(a, a); ^~~~~~~~~~ Father::func_para1 jicheng.cpp:17:7: note: 'Father::func_para1' declared here int func_para1(int a, int b) ^ 1 error generated
参考: https://blog.csdn.net/cpp12341234/article/details/52195993
#include<iostream> using namespace std; class Father{ public: //#if 0 //virtual int func_para1(int a) int func_para1(int a) { // cout << "my para is: " + a << endl; // cout << "my para is: %d ", a << endl; cout << "my para is: " << a << endl; return 0; } //#else //virtual int func_para1(int a, int b) int func_para1(int a, int b) { // cout << "my para is: " + a << endl; // cout << "my para is: %d ", a << endl; cout << "Father two para mode, my para is: " << a << endl; return 0; } //#endif }; //class Child :Father{ //class Child :protected Father{ class Child :public Father{ public: #if 0 //如果全部注释child类的实现,子类可以使用父类的方法。可是,我们打开了其中的任何一个,就意味着我们要在子类中重写父类的方法, //也就是说,只要子类出现与父类的同名函数,子类就不会继承父类的同名函数。如果父类中有重载的话,我们需要哪个,就必须实现哪个。没有实现的函数,编译时会提示找不到。 //参考: https://blog.csdn.net/cpp12341234/article/details/52195993 int func_para1(int a) { cout << "Child my para is: " << a << endl; return 0; } #if 1 int func_para1(int a, int b) { cout << "Child my para is: " << a << endl; return 0; } #endif #endif }; int main(int argc, char *argv[]) { int a=5; //Father father = new Father(); //Father father; //Father *father = new Father(); //father->func_para1(a); #if 0 Child *child = new Child(); child->func_para1(a, a); child->func_para1(a); #endif Child child; Father *father = &child; father->func_para1(a, a); child.func_para1(a, a); return 0; }