- 虚函数
- 虚析构
- 纯虚函数示例
- overwrite
- 虚函数原理和vtb
- 虚函数示例代码
- 虚析构示例代码
- vtab示例代码
虚析构虚函数主要用来解决基类指针指向派生类时实际指向基类的问题 问题示例
纯虚函数示例虚析构是为了解决基类指针指向派生类时调用指针进行析构不能析构派生类可能导致内存泄漏问题 问题示例
overwrite纯虚函数是基类为派生类专门声明的接口,因此派生类如果需要实例化则必须对该纯虚函数进行定义,否则定义不完整不能实例化。
类似纯虚类也是,专门用来提供派生类覆盖模板,派生类必须完全实现才能实例化。
-
用在基类函数后表示该函数必须被派生类进行重写
-
用在派生类明确表示是对基类的函数覆盖,防止写错函数名或参数表
此处实验实例化含未实现虚函数的对象实例化会报链接错误,即实例化的类中不能包含未被定义的函数
- 首先区分栈区,代码区,比如new class ,new出的只是类的成员变量部分,而函数在代码区
- 如果一个类包含虚函数会在new出的对象开始部分增加一个指针大小的空间,用来存储vtab的地址
- 如果一个类包含虚函数类的大小会增加(64位上前8后4)
- 含虚函数的类首地址指向虚函数表,而同一个虚函数类同继承的不同实例指向同一个vtab,同一个虚函数的不同继承的实例指向不同vtab
- 测试代码
#includeusing namespace std; class A{ public: void Pt(){ std::cout << "Pt A" << std::endl; } }; class B:public A{ public: void Pt(){ std::cout << "Pt B" << std::endl; } }; int main(int argc,char** argv){ A* oa = dynamic_cast(new B); oa->Pt();//Pt A return 0; }
返回顶部
虚析构示例代码#includeusing namespace std; class A{ public: A(){std::cout << "construct A" << std::endl;} ~A(){std::cout << "disconstruct A" << std::endl;} }; class B:public A{ public: B(){std::cout << "construct B" << std::endl;buf = new char[50];} ~B(){std::cout << "disconstruct B" << std::endl;delete buf;} private: char* buf; }; int main(int argc,char** argv){ A* oa = dynamic_cast(new B); delete oa; return 0; }
返回顶部
vtab示例代码#include#include #include #include std::string to_hex(unsigned char* data, int len) { std::stringstream ss; ss << std::uppercase << std::hex << std::setfill('0'); for (int i = 0; i < len; i++) { ss << std::setw(2) << static_cast (data[i]); } return ss.str(); } class A{ private: int a; public: A():a(11){}; void p(); }; class B{ protected: int a; public: B():a(11){}; virtual void p(){ std::cout << "B Class"<< a << std::endl;}; }; class C:public B{ public: void p(){std::cout << "C Class"<< a << std::endl;}; }; int main() { A a1; unsigned char* p1 = reinterpret_cast (&a1); std::cout << to_hex(p1,sizeof(a1)) << std::endl;//0B000000 std::cout < (&b1); std::cout << to_hex(pb1,sizeof(b1) ) << std::endl;//40204000000000000B0000009D7F0000 std::cout < (&c1); std::cout << to_hex(pc1,sizeof(c1) ) << std::endl;//28204000000000000B0000009D7F0000 std::cout < (&c2); std::cout << to_hex(pc2,sizeof(c2) ) << std::endl;//28204000000000000B0000009D7F0000 std::cout < 返回顶部



