一些概念

POD

类的构造和析构

C++

构造和析构函数调用顺序SJLin-CSDN博客析构函数顺序

当定义一个类时,我们显式或隐式地指定在此类型的对象「拷贝」、「移动」、「赋值」、「销毁」时做什么——(定义一个类时就在它的生命周期中的几个固定节点定义了附加动作)

拷贝构造函数

拷贝构造函数的参数是对象的引用;
在这些情况调用:

  • 用一个对象初始化另一个对象;
  • 函数调用时参数有类的对象;
  • 函数返回时返回值是类的对象;

    拷贝赋值运算符

    移动构造函数(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:多继承情况下某些基类的函数名冲突?

    1. # 加上域,可以避免多继承下的冲突
    2. d.B1::ib = 1;
    3. d.B2::ib = 2;
  • ref:这一篇基本讲了所有情形:虚表的内存布局(c++)_陈嘉怡的专栏-CSDN博客

  • 重复继承下的冲突

    • 派生类多继承了继承同一个基类B的两个基类B1和B2;
    • C++的实现,是老老实实在内存中准备两份分别属于B1和B2的继承自B的成员和虚表;
    • 如果要访问继承于基类B的成员,连域也没法避免而二义性了;【待确认】
    • 这种情况下空间的浪费是必然的;因为B的实现无论如何存了两份;
  • 这种重复继承的情况,其形状也不是菱形的;需要使用虚继承才能实现真正的“菱形”;

虚继承

  1. // 第一种情况:        
  2. class a          
  3. {             
  4. virtual void func();  
  5. };             
  6. class b:public virtual a  
  7. {             
  8. virtual void foo();  
  9. };             
  10. // 第二种情况:          
  11. class a           
  12. {               
  13. virtual void func();  
  14. };              
  15. class b :public a      
  16. {              
  17. virtual void foo(); 
  18. };              
  19.                 
  20. // 第三种情况            
  21. class a           
  22. {                
  23. virtual void func();  
  24.   char x;          
  25. };             
  26. class b:public virtual a    
  27. {            
  28. virtual void foo();   
  29. }; 
  30. // 第四种情况:
  31. class a
  32. {
  33. virtual void func();
  34. char x;
  35. };
  36. class b:public a
  37. {
  38. virtual void foo();
  39. };