静态变量
所有对象都共享同一份数据
编译阶段分配内存
类内声明类外初始化
1 2 3 4 5 6 7 8 9 10 11
   | class P{     public: 	    static int m_A;   } int P::m_A = 100; 
  int main(){     P p1;     cout << p1.m_A;      cout << P::m_A;  }
 
  | 
 
常函数
常函数只能修改mutable修饰的成员变量
常对象只能调用常函数,常对象只能修改mutable修饰的成员变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | class C{     public:     	int m_A;     	mutable int m_B;       	void test() const{              this->m_A = 100;              this->m_B = 100;          }     	     	void func(){} }
  void test2(){     const C c;      c.m_A = 100;      c.m_B = 100;      c.test();     c.func();  }
 
  | 
 
运算符重载
左移运算符
1 2 3 4 5 6 7 8 9 10
   | class Person{     public:     	int m_Age; }
  ostream& operator<<(ostream& cout, Person& p){     cout << "p.m_Age" << p.m_Age << endl;     return cout;  }
 
 
  | 
 
递增运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | class MyInteger { public:     int m_num;
           MyInteger &operator++() {         m_num++;         return *this;     }
           MyInteger operator++(int) {         MyInteger tmp = *this;         m_num++;         return tmp;     } };
 
  | 
 
函数调用运算符重载
1 2 3 4 5 6 7 8 9 10 11
   | class Call {          void operator()() {         cout << "__call__" << endl;     } }
  void test_call(){     MyInteger i{};     i();  }
 
  | 
 
继承

继承构造析构顺序:
 构造:先父后子
 析构:先子后父
菱形继承问题,会继承多份顶层基类的数据,浪费资源,使用虚继承优化,利用虚基类指针维护虚基类表中一份数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
   | #include "iostream"
  using namespace std;
 
  void extend() {     class Parent {     public:         int m_Age;     };
      class Father : public Parent {     };
      class Mama : public Parent {     };     class Son : public Father, public Mama {     public:         int m_Age;     };     Son son;     son.Father::m_Age = 30;     son.Mama::m_Age = 20;     cout << son.Father::m_Age << endl;      cout << son.Mama::m_Age << endl;       }
 
  void virtual_extend() {          class Parent {     public:         int m_Age;     };
           class Father : virtual public Parent {     };
      class Mama : virtual public Parent {     };
      class Son : public Father, public Mama {     public:         int m_Age;     };     Son son;     son.Father::m_Age = 30;     son.Mama::m_Age = 20;     cout << son.Father::m_Age << endl;      cout << son.Mama::m_Age << endl;       }
  int main() {     cout << "菱形继承" << endl;     extend();     cout << "虚继承" << endl;     virtual_extend();     return 0; }
 
  | 
 
多态
虚继承
解决菱形继承,同一份数据在子类中存储多次,资源浪费问题
虚继承保证数据只继承一份,使用虚基类指针(vbptr)指向虚基类表(vbtable),继承的是指针而不是值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
   | #include "iostream"
  using namespace std;
 
  void extend() {     class Parent {     public:         int m_Age;     };
      class Father : public Parent {     };
      class Mama : public Parent {     };     class Son : public Father, public Mama {     public:         int m_Age;     };     Son son;     son.Father::m_Age = 30;     son.Mama::m_Age = 20;     cout << son.Father::m_Age << endl;      cout << son.Mama::m_Age << endl;       }
 
  void virtual_extend() {          class Parent {     public:         int m_Age;     };
           class Father : virtual public Parent {     };
      class Mama : virtual public Parent {     };
      class Son : public Father, public Mama {     public:         int m_Age;     };     Son son;     son.Father::m_Age = 30;     son.Mama::m_Age = 20;     cout << son.Father::m_Age << endl;      cout << son.Mama::m_Age << endl;       }
  int main() {     cout << "菱形继承" << endl;     extend();     cout << "虚继承" << endl;     virtual_extend();     return 0; }
 
  | 
 
虚析构
多态时,采用父类指针指向子类对象时,释放父类指针不会调用子类析构函数,若子类中存在堆区数据,会存在内存泄漏。使用虚析构解决此类问题。
含纯虚析构的类为抽象类,纯虚析构需要在类外实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
   | #include <iostream>
  using namespace std;
 
  void not_virtual() {     class Animal {     public:         ~Animal() {             cout << "~Animal()" << endl;         }     };
      class Dog : public Animal {     public:         string *m_name;
          Dog(string name) {             m_name = new string(name);             cout << "Dog()" << endl;         }
          ~Dog() {             if (m_name) {                 delete m_name;                 m_name = nullptr;             }             cout << "~Dog()" << endl;         }     };
      Animal *animal = new Dog("wangcai");     delete animal; }
 
  void virtual_destruct() {     class Animal {     public:         virtual ~Animal() {             cout << "~Animal()" << endl;         }     };
      class Dog : public Animal {     public:         string *m_name;
          Dog(string name) {             m_name = new string(name);             cout << "Dog()" << endl;         }
          ~Dog() {             if (m_name) {                 delete m_name;                 m_name = nullptr;             }             cout << "~Dog()" << endl;         }     };
 
      Animal *animal = new Dog("wangcai");     delete animal; }
  class Test {               virtual ~Test() = 0; };
  Test::~Test() {     cout << "~Test()" << endl; }
  int main() {               not_virtual();               virtual_destruct();     return 0; }
 
  |