c++多态,为何只能通过指针或引用实现


本文目的

 
  在c++的多态中,如果一个基类的虚函数被派生类重写,那么把基类的指针指向派生类,就能够通过基类调用被派生类重写的这个虚函数。(对于这点有疑问的,可以看我之前写的C++多态,虚函数,虚函数表,gcc下的单继承,多继承,虚继承的内存布局)。那么如果不用指针或引用会如何?

 class Animal{
      public:
          virtual void eat()
          {
          	cout<<"能吃什么就吃什么"<<endl;
          }
          virtual void run(){}
      private:
          int name;
 };
 class Dog  : public Animal{
      public:
          virtual void eat(){
          	cout<<"吃狗粮"<<endl;
          }
          virtual void shout(){}
      private:
      	int age;
 };
 int main()
 {
 	Dog dog;
 	Animal&animal1 = dog;
 	Animal* animal2 = new Dog();
 	Ainmal animal3 = dog;
 	
 	animal1.eat();
 	animal2->eat();
 	animal3.eat();
 }

在这里插入图片描述
不用指针或引用,我们直接取值时,就不能调用多态。那么为什么呢?


内存切割

 
  之所以能够多态是因为虚函数的内存布局,以之前代码为例,Dog类的内存布局在gcc下如图:
在这里插入图片描述
当我们执行以下代码时

	Animal&animal1 = dog;
 	Animal* animal2 = new Dog();

将会产生内存切割,图中Dog类的Animal部分被animal1和animal2得到。从而实现多态机制。

	Ainmal animal3 = dog;

  那么为什么 这样调用就不能通过内存切割实现多态呢?

我在《深度探索C++对象模型》中找到了答案:

  “一个pointer或一个reference之所以支持多态,是因为它们并不引发内存任何“与类型有关的内存委托操作; 会受到改变的。只有它们所指向内存的大小和解释方式 而已”

对这句话解释就是:

  1. 指针和引用类型只是要求了基地址和这种指针所指对象的内存大小,与对象的类型无关,相当于把指向的内存解释成指针或引用的类型。
  2. 而把一个派生类对象直接赋值给基类对象,就牵扯到对象的类型问题,编译器就会回避之前的的虚机制。从而无法实现多态。

尾语

  《深度探索C++对象模型》有很多东西都比较解惑,不多第一遍读的时候,会有很多疑惑,也会遗漏很多细节,不过多读几遍,感觉就会很不一样,之前存在的问题,可能都会被解决。

以上

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值