类中的构造/析构函数、拷贝构造函数和赋值操作符使用||虚拟继承和虚基类原理

明确一点,就算是一个空类,编译器也会加上默认的构造函数和拷贝构造函数、析构函数、赋值运算符。

构造函数:实例化一个对象,数据成员初始化以及分配内存的作用。特点是名字和类名一样,没有返回值。
构造函数可以被重载,有多个,带不同参数。析构函数一般为虚函数,只有一个不能重载。

拷贝构造函数是C++独有的,它是一种特殊的构造函数,用基于同一类的一个对象构造和初始化另一个对象。
A a;
A b(a);
A b=a; 都是拷贝构造函数来创建对象b
强调:这里b对象是不存在的,是用a 对象来构造和初始化b的!!
在C++中,3种对象需要复制,此时拷贝构造函数会被调用
1 一个对象以值传递的方式传入函数体
2 一个对象以值传递的方式从函数返回
3 一个对象需要通过另一个对象进行初始化

注意点:系统提供的默认拷贝构造函数工作方式是内存拷贝,也就是浅拷贝。如果复制的对象中引用了一个外部内容(例如分配在堆上的数据、指针),那么在复制这个对象的时候,让新旧两个对象指向同一个外部内容,析构两次就会崩溃,所以需要重载拷贝构造函数,完成深拷贝。A (const A&other)

当一个类的对象向该类的另一个对象赋值时,就会用到该类的赋值函数。
A a;
A b;
b=a;
强调:这里a,b对象是已经存在的,是用a 对象来赋值给b的!!
A& operator = (const A& other)

拷贝和赋值的区别:
拷贝是一个对象来初始化一块内存,这块内存就是新对象的内存区域;赋值是一个对象已经初始化了,再用另一个对象赋值。

如果不想写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,最简单的办法是将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。

虚拟继承和虚函数完全不一样。
虚函数不说了。
虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。

原理:
一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。
实际上,vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间。
在这里我们可以对比虚函数的实现原理:他们有相似之处,都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间)。
虚基类依旧存在继承类中,只占用存储空间;虚函数不占用存储空间。
虚基类表存储的是虚基类相对直接继承类的偏移;而虚函数表存储的是虚函数地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值