静态变量
所有对象都共享同一份数据
编译阶段分配内存
类内声明类外初始化
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; }
|