006 子类父类赋值兼容规则

Posted guojun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了006 子类父类赋值兼容规则相关的知识,希望对你有一定的参考价值。

 

子类和父类的赋值兼容规则

1.同名隐藏(非常重要)

当子类的成员方法(show)和父类的成员方法(show)的名字相同的时候,父类的所有(show)方法,都不能用子类的对象来调用了,这种现象就是同名隐藏。

#include <iostream>
using namespace std;

class Base{
public:
  Base():d(0){}
  ~Base(){}
  void show(){
    cout << "Base show" << endl;
  }
  void show(int i){
    cout << "Base show(" << i << endl;
  }
private:
  int d;
};

class D : public Base{
public:
  D():x(0){}
  ~D(){}
  void show(){
    cout << "D show" << endl;
  }
private:
  int x;
};
int main(){
  D d;
  d.show();
  //编译不过
  //d.show(20);//因为子类也定义了show方法,所以父类的2个show方法,就都不可以用子类的对象来调用了
  d.Base::show(20);
}

2.子类和父类的对象/指针/引用赋值

可以用子类的对象/地址/引用去赋值给父类,叫对象切片,或者叫向上赋值,但是反过来是不可以的。

赋值后,只能调用父类里的成员方法,不能调用子类里的成员方法。

#include <iostream>
using namespace std;

class Base{
public:
  Base():d(0){}
  ~Base(){}
  void show(){
    cout << "Base show" << endl;
  }
  void show(int i){
    cout << "Base show(" << i << endl;
  }
private:
  int d;
};

class D : public Base{
public:
  D():x(0){}
  ~D(){}
  void show(){
    cout << "D show" << endl;
  }
  void list(){
    cout << "D list" << endl;
  }
private:
  int x;
};

int main(){
  D d;
    
  Base b;
  b = d;
  b.show();
  //编译不过
  //b.list();//不可以用父类的对象调用子类的方法  
    
  Base *pb;
  pb = &d;
  pb->show();//调用的是父类的show方法
  //编译不过
  //pb->list();//不可以用父类的指针调用子类的方法                                                                   

  Base &ps = d;
  ps.show();//调用的是父类的show方法
  //编译不过
  //ps.list();//不可以用父类的引用调用子类的方法 
}
3. 虚函数

当用子类的对象/指针/引用去赋值给父类时,如果子类和父类都有同名方法show,当调用show的时候,发现调用的是父类的show方法。如果想要达到调用子类的show方法的效果的话,必须用virtual关键字,修饰父类的show方法,而且父类必须是指针或者引用,不可以是对象。

#include <iostream>
using namespace std;

class Base{
public:
  Base():d(0){}
  ~Base(){}
  virtual void show(){//虚函数
    cout << "Base show" << endl;
  }
  void show(int i){
    cout << "Base show(" << i << endl;
  }
private:
  int d;
};

class D : public Base{
public:
  D():x(0){}
  ~D(){}
  void show(){
    cout << "D show" << endl;
  }
  void list(){
    cout << "D list" << endl;
  }
private:
  int x;
};

int main(){
  D d;

  Base b;
  b = d;
  b.show();//调用的是父类的show

  Base *pb;
  pb = &d;
  pb->show();//调用的是子类的show

  Base &ps = d;
  ps.show();//调用的是子类的show
}

以上是关于006 子类父类赋值兼容规则的主要内容,如果未能解决你的问题,请参考以下文章

总结C++基类与派生类的赋值兼容规则

赋值兼容原则

C++ 继承与派生中的赋值兼容规则问题探究

C++ 继承与派生中的赋值兼容规则问题探究

C++继承多态总结

第48课 同名覆盖引发的问题------子类中函数重写遇上赋值兼容