标签:派生类 targe lan http 对象模型 指定 编译 href 成员
语言中直接支持面向对象程序设计的部分;
对于各种支持的底层实现机制。(没看懂……)
i. static function
ii. non static function
iii. virtual function
i. static member data
ii. non static member data
i. non static member data
ii. vptr(虚函数表指针)
iii. vbptr(虚基类表指针)
i. static member data(存储在静态存储区)
ii. 成员函数(存储在代码区)
简称vtbl。存放着指针,这些指针指向该类每一个虚函数。虚表中的函数地址将按声明时的顺序排列。vtbl在类声明后就形成了,vptr是编译器生成的。
vbptr指向的表,用于存放虚继承中,虚基类存储相对于虚基类表指针的偏移量。
class Base { public: Base (int a = 1):base(a){} void fun0(){cout << base << endl;} int base; }; class Derive:public Base { public: Derive (int a = 2):derive(a){} void fun1(){cout << base1 << endl;} int derive; };
class Base1 { public: Base1 (int a = 2):base1(a){} void fun1(){cout << base1 << endl;} int base1; }; class Base2 { public: Base2 (int a = 3):base2(a){} void fun2(){cout << base2 << endl;} int base2; }; class Derive: public Base1, public Base2 { public: Derive (int value = 4):derive (value){} void fun3(){cout << derive << endl;} int derive; };
class Base { public: Base (int a = 1):base(a){} void fun0(){cout << base << endl;} int base; }; class Base1 { public: Base1 (int a = 2):base1(a){} void fun1(){cout << base1 << endl;} int base1; }; class Base2 { public: Base2 (int a = 3):base2(a){} void fun2(){cout << base2 << endl;} int base2; }; class Derive: public Base1, public Base2 { public: Derive (int value = 4):derive (value){} void fun3(){cout << derive << endl;} int derive; };
注:菱形继承存在二义性问题,编译都不通过,只能通过指定特定基类的方式进行访问基类变量。
Derive d;
d.base =3; // 不正确
d.Base1::base = 3; // 正确
class Base { public: Base (int a = 1):base(a){} virtual void fun0(){cout << base << endl;} int base; }; class Derive:public Base { public: Derive (int a = 2):derive(a){} virtual void fun0(){}; virtual void fun1(){cout << derive << endl;} int derive; };
注:派生类中新增的虚函数追加到虚函数表后面。
class Base1 { public: Base1 (int a = 2):base1(a){} virtual void fun1(){cout << base1 << endl;} int base1; }; class Base2 { public: Base2 (int a = 3):base2(a){} virtual void fun2(){cout << base2 << endl;} int base2; }; class Derive: public Base1, public Base2 { public: Derive (int value = 4):derive (value){} virtual void fun3(){cout << derive << endl;} int derive; };
注:派生类中新增的虚函数,追加到第一个基类的虚函数表的后面。
class Base { public: Base (int a = 1):base(a){} virtual void fun0(){cout << base << endl;} int base; }; class Base1:public Base { public: Base1 (int a = 2):base1(a){} virtual void fun1(){cout << base1 << endl;} int base1; }; class Base2:public Base { public: Base2 (int a = 3):base2(a){} virtual void fun2(){cout << base2 << endl;} int base2; }; class Derive: public Base1, public Base2 { public: Derive (int value = 4):derive (value){} virtual void fun3(){cout << derive << endl;} int derive; };
注:分析时,由上到下依次分析。存在二义性问题和内存冗余问题。
新增虚基类指针,指向虚基类表,虚基类表中首项存储虚基类指针的偏移量,接下来依次存储虚基类的偏移量(偏移量是相对于虚基类表指针的存储地址)。
class Base { public: Base (int a = 1):base(a){} void fun0(){cout << base << endl;} int base; }; class Base1:virtual public Base { public: Base1 (int a = 2):base1(a){} void fun1(){cout << base1 << endl;} int base1; };
class Base1 { public: Base1 (int a = 2):base1(a){} void fun1(){cout << base1 << endl;} int base1; }; class Base2 { public: Base2 (int a = 3):base2(a){} void fun2(){cout << base2 << endl;} int base2; }; class Derive:virtual public Base1, virtual public Base2 { public: Derive (int value = 4):derive (value){} void fun3(){cout << derive << endl;} int derive; };
第一种形式:
class Base { public: Base (int a = 1):base(a){} void fun0(){cout << base << endl;} int base; }; class Base1:virtual Base { public: Base1 (int a = 2):base1(a){} void fun1(){cout << base1 << endl;} int base1; }; class Base2:virtual Base { public: Base2 (int a = 3):base2(a){} void fun2(){cout << base2 << endl;} int base2; }; class Derive:virtual public Base1, virtual public Base2 { public: Derive (int value = 4):derive (value){} void fun3(){cout << derive << endl;} int derive; };
注:分析派生类的内存分布时,也是由上到下分析。虚继承将基类置于内存末尾,但是置于末尾的顺序也有一定的次序。首先Base先放到末尾,然后Base1放到末尾,最后Base2放到末尾。
第二种形式:
class Base { public: Base (int a = 1):base(a){} void fun0(){cout << base << endl;} int base; }; class Base1:virtual public Base { public: Base1 (int a = 2):base1(a){} void fun1(){cout << base1 << endl;} int base1; }; class Base2:virtual public Base { public: Base2 (int a = 3):base2(a){} void fun2(){cout << base2 << endl;} int base2; }; class Derive: public Base1, public Base2 { public: Derive (int value = 4):derive (value){} void fun3(){cout << derive << endl;} int derive; };
注:分析的原则,从上到下,依次分析。
class Base { public: Base (int a = 1):base(a){} virtual void fun0(){cout << base << endl;} int base; }; class Base1:virtual Base { public: Base1 (int a = 2):base1(a){} virtual void fun1(){cout << base1 << endl;} int base1; };
与普通的包含虚函数的单继承相比,派生类拥有自己的虚函数表以及虚函数表指针,而不是与基类共用一个虚函数表。注意虚函数表指针和虚基类表指针的存储顺序。
class Base1 { public: Base1 (int a = 2):base1(a){} virtual void fun1(){cout << base1 << endl;} int base1; }; class Base2 { public: Base2 (int a = 3):base2(a){} virtual void fun2(){cout << base2 << endl;} int base2; }; class Derive:virtual public Base1, virtual public Base2 { public: Derive (int value = 4):derive (value){} virtual void fun3(){cout << derive << endl;} int derive; };
第一种形式:
class Base { public: Base (int a = 1):base(a){} virtual void fun0(){cout << base << endl;} int base; }; class Base1:virtual public Base { public: Base1 (int a = 2):base1(a){} virtual void fun1(){cout << base1 << endl;} int base1; }; class Base2:virtual public Base { public: Base2 (int a = 3):base2(a){} virtual void fun2(){cout << base2 << endl;} int base2; }; class Derive: virtual public Base1, virtual public Base2 { public: Derive (int value = 4):derive (value){} virtual void fun3(){cout << derive << endl;} int derive; };
第二种形式:
class Base { public: Base (int a = 1):base(a){} virtual void fun0(){cout << base << endl;} int base; }; class Base1:virtual public Base { public: Base1 (int a = 2):base1(a){} virtual void fun1(){cout << base1 << endl;} int base1; }; class Base2:virtual public Base { public: Base2 (int a = 3):base2(a){} virtual void fun2(){cout << base2 << endl;} int base2; }; class Derive: virtual public Base1,virtual public Base2 { public: Derive (int value = 4):derive (value){} virtual void fun3(){cout << derive << endl;} int derive; };
自行脑补C++类对象的内存结构……
注:上述虚函数中,如果派生类重写了基类的虚函数,则对应虚函数表中的虚函数应该修改成重新后的虚函数,即Base::fun()->Derive::fun()。
http://www.cnblogs.com/raichen/p/5744300.html
标签:派生类 targe lan http 对象模型 指定 编译 href 成员
原文地址:http://www.cnblogs.com/longcnblogs/p/7642951.html