c++学习--多态总结

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;
}







猜你喜欢

转载自blog.csdn.net/u010029439/article/details/80640570