一些概念
类的构造和析构
C++
当定义一个类时,我们显式或隐式地指定在此类型的对象「拷贝」、「移动」、「赋值」、「销毁」时做什么——(定义一个类时就在它的生命周期中的几个固定节点定义了附加动作)
拷贝构造函数
拷贝构造函数的参数是对象的引用;
在这些情况调用:
- 用一个对象初始化另一个对象;
- 函数调用时参数有类的对象;
- 函数返回时返回值是类的对象;
拷贝赋值运算符
移动构造函数(C++11)
移动构造函数和移动赋值运算符、即移动语义是C++11新出现的概念;
移动构造函数的参数是一个右值引用(T&& v)移动赋值运算符(C++11)
析构函数
在析构函数中应该将delete或free的指针赋值为空;
默认构造函数
Java
Java中的构造函数
Java中的构造函数和C++的行为整体上一样,但不完全一样;
C++的构造函数执行阶段对象还没有构造,虚函数表也没有构造,所以在C++的构造函数中不能调用虚函数;
Java的构造函数中可以调用成员函数完成虚函数行为;——待深入理解;
Java中的析构函数
Java中内存的分配和释放都交给了GC,所以不存在开放给程序员的析构函数概念;
如果非要这个需求,可能需要了解JVM,finalize相关机制:JVM—finalize方法 - 简书
继承
多继承
- 注:这里的多继承指的是——从多个直接基类派生类的能力
CPP的多继承
- C++选择可以允许一个派生类继承多个基类
- 这样也带来一些问题:
Q:多继承情况下某些基类的函数名冲突?
# 加上域,可以避免多继承下的冲突d.B1::ib = 1;d.B2::ib = 2;
ref:这一篇基本讲了所有情形:虚表的内存布局(c++)_陈嘉怡的专栏-CSDN博客
- 虚函数表在对象内存中的布局 - 简书
Java下的“声明多继承”
菱形继承/重复继承
- 虚函数表在对象内存中的布局 - 简书
重复继承下的冲突
- 派生类多继承了继承同一个基类B的两个基类B1和B2;
- C++的实现,是老老实实在内存中准备两份分别属于B1和B2的继承自B的成员和虚表;
- 如果要访问继承于基类B的成员,连域也没法避免而二义性了;【待确认】
- 这种情况下空间的浪费是必然的;因为B的实现无论如何存了两份;
- 这种重复继承的情况,其形状也不是菱形的;需要使用虚继承才能实现真正的“菱形”;
虚继承
- 关于C++中的虚拟继承的一些总结 - 鲸小鱼|相信所以选择 - 博客园
- 虚继承存在的意义是在多重继承的情况下
- 虚继承下的派生类像虚函数那样在虚表中用一个
// 第一种情况:class a{virtual void func();};class b:public virtual a{virtual void foo();};// 第二种情况:class a{virtual void func();};class b :public a{virtual void foo();};// 第三种情况class a{virtual void func();char x;};class b:public virtual a{virtual void foo();};// 第四种情况:class a{virtual void func();char x;};class b:public a{virtual void foo();};
