《深度探索C++物件模型》第五章Semantics of Construction,Destruction, and Copy_學習筆記
Presence of a Pure Virtual Function
可以靜態呼叫純虛擬函式,而不能通過虛擬機制呼叫。在呼叫時,如果你未定義該純虛擬函式,則可以通過編譯階段,但在連結階段產生錯誤。
#include <iostream> class A { public: virtual void vf() const = 0; }; void A::vf() const { std::cout << "virtual void A::vf() const\n"; } class D: public A { public: virtual void vf() const{ this->A::vf(); std::cout << "virtual void B::vf() const\n"; } }; int main(int argc, char* argv[]) { D o; o.vf(); return 0; }
結果為:。
5.1 “無繼承”下的物件構造
物件產生 三種 方式:global、local、heap。
C中,global沒有明確定義初始化操作,被視為“臨時性的定義”,因此可定義多次,而多個例項被連結器摺疊,只剩一個實體,放在data segment中的BSS空間(用於存放未初始化資料)之內。
C++中,global被視為完全定義,即僅限定義一次,而且已初始化。
Abstract Data Type
inline X::X(int x = 0): __x (x) {}將比 x.__x = x; 更高效,因為當函式的activation record被放入initialization list常量就可進入object的記憶體。
若: X o; // => X o; o.__x = 0; 被擴充套件成簡單的 member_by_member常量指定。
而:X *p = new X; //=> X *p = __new( sizeof (X)); if(p != o) p->X::X( ); 呼叫預設建構函式。
為繼承作準備
若class中含virtual function,則將會增加 vptr ,且引發 class 的程式碼膨脹作用。
C++Standard要求編譯器儘量將nontrivial data members的實際合成操作直到遇到使用場合為止。如: X *p = new X; *p = local;copy assignment operator將在*p = local時才合成。如定義類X: class X { public: X(int x = 0): _x = x {} virtual void vf() const; } 則類X的建構函式,將被如下擴充套件: X::X(X *this, int x= 0) { this->_vptr_X = vtbl_point; this->_x = x; }
5.2 繼承體系下的物件構造
當執行 T object; 時,將伴隨:
1、記錄member initialization list中data members初始化操作按宣告順序放進 constructor 函式。
2、如data member object未出現在member initialization list、但有default constructor,則呼叫該constructor。
3、如有virtual ,則指定適當 vptr。
4、所有base class constrcutor
#include <iostream>
using namespace std;
class A {
public:
A& operator= (const A& t)
{
std::cout << "virtual A& A::operator= (const A& t)" << endl;
return *this;
}
};
class B: virtual public A { };
class C: virtual public A { };
class D: public B, public C { };
int main(int argc, char* argv[])
{
D d1, d2;
d1 = d2;
return 0;
}
執行結果:。