智能指针其实不是一个指针。它是一个用来帮助我们管理指针的类,维护其生命周期的类。有了它,妈妈再也不用担心我的内存泄露啦!
需要解决的问题:
释放内存方法一:同归于尽! auto_ptr
释放内存方法二:引用计数!
实现,有两个问题需要解决
class Counter { friend class SmartPointPro; public: Counter(){ ptr = NULL; cnt = 0; } Counter(Object* p){ ptr = p; cnt = 1; } ~Counter(){ delete ptr; } private: Object* ptr; int cnt; };
class SmartPointPro { public: SmartPointerPro(Object* p){ ptr_counter = new Counter(p); } SmartPointerPro(const SmartPointerPro &sp){ ptr_counter = sp.ptr_counter; ++ptr_counter->cnt; } SmartPointerPro& operator=(const SmartPointerPro &sp){ ++sp.ptr_counter->cnt; --ptr_counter.cnt; if(ptr_counter.cnt == 0) delete ptr_counter; ptr_counter = sp.ptr_counter; } ~SmartPointerPro(){ --ptr_counter->cnt; if(ptr_counter.cnt == 0) delete ptr_counter; } private: Counter *ptr_counter; };
//机智的Meyers写法,优雅而线程安全
class Singleton{ private: Singleton(){} Singleton(const Singleton& s){} Singleton& operator=(const Singleton& s){} public: static Singleton* GetInstance() { static Singleton instance; return &instance; } }
struct Q{ char c; int num1; double num2; };
出现频率: 5星 题目难度: 4星 使用范围: 所有公司
虚函数表: 一个类的虚函数的地址表,所有对象都是通过它来找到合适的虚函数. 他就是这个类的"四十二章经"
虚函数表指针: 每个类的对象实例都拥有一个指针指向这张虚函数表(一般在对象实例的最前面),它帮助对象找到这张表的地址,然后就可以遍历其中的函数指针,调用相应的函数
注意:虚函数表一个类有一个,而不是一个对象有一个
子类的虚函数表是子类的,从父类拷贝一份过来,并进行修改. 和父类并不是共享
那么发生继承覆盖时发生了什么呢?
普通函数不进入虚函数表
C++本身是没有类地址的,虚函数表放在代码段或者数据段的
如果没有在子类中重载,调用的就还是父类的虚函数实现.
先看下面的一段代码
class A { public: int a; virtual void myfunA(){} }; class B : virtual public A{ public: virtual void myfunB(){} }; class C : virtual public A{ public: virtual void myfunC(){} }; class D: public B, public C{ public: virtual void myfunD(){} }; int main (){ cout << sizeof(A) << endl; cout << sizeof(B) << endl; cout << sizeof(C) << endl; cout << sizeof(D) << endl; return 0; }
在VC++下,答案为: 8, 16, 16, 24
在g++ 32位机器下,答案为: 8, 12, 12, 16
分析VC++
单一的一般继承
[图片上传失败...(image-5efc6-1516850329498)]
多重继承
[图片上传失败...(image-9653a5-1516850329498)]
钻石形重复继承--没有使用虚继承
[图片上传失败...(image-322c8a-1516850329498)]
钻石形多重虚拟继承,下面给出gcc的结果
[图片上传失败...(image-80a507-1516850329498)]