コンストラクション関数のthisポインタ

3393 ワード

明:ウェブページC++FAQ Liteの作者Marshall Clineと翻訳者申旻に感謝します.「C++言語コア」の著者Gregory SatirとDoug Brown、翻訳者の張銘沢に感謝します.----原理----一部の人は構造関数でthisポインタを使用すべきではないと思っています.この場合、thisオブジェクトはまだ完全に形成されていないからです.ただし、注意すれば、構造関数でthisポインタを使用することができます:●関数体では●初期化リストでは、「オブジェクトが完全に形成されていない」ため、「何もない」という意味ではありません.コンストラクション関数(およびそのchaining)に入る前に、Compilerは:●classのinstanceにメモリを割り当てる●実行時刻システムを構築するために必要な情報(vtblなど)●デフォルトですべてのクラスメンバーを構築する-------------------------------【可能】-----------------------------------------------------------コンストラクション関数の関数体(またはコンストラクション関数によって呼び出される関数)【可能】信頼性の高いアクセス:●ベースクラスで宣言されたデータメンバー●コンストラクション関数が属するクラスで宣言されたデータメンバーこれは、コンストラクション関数の関数体が実行されると完全に確立されることが保証されているためである.(またはコンストラクション関数によって呼び出された関数)【いいえ】下に呼び出される:●派生クラスによって再定義された虚関数これは、ベースクラスのコンストラクション関数の実行中に「オブジェクトはまだ派生クラスのオブジェクトではない」ためである.【時々】実行可能:●thisオブジェクトのいずれかのデータ・メンバーを別のデータ・メンバーに渡す初期化プログラムは、データ・メンバーが初期化されていることを確認する必要があります.良いニュースは、使用するコンパイラに依存しない顕著な言語ルールを使用して、そのデータ・メンバーがすでに初期化されているかどうかを確認することです.(またはまだ)初期化されていません.悪いメッセージは、これらの言語ルール(たとえば、ベースクラスのサブオブジェクトが最初に初期化されるなど)を知る必要があります.(複数および/またはダミー継承がある場合は、この順序を問合せ!)、クラスで定義されたデータ・メンバーは、クラスで宣言された順序に従って初期化されます.これらのルールが分からない場合は、thisオブジェクトからデータ・メンバーを渡さないでください.(thisキーワードが明示的に使用されているかどうかにかかわらず)他のデータ・メンバーへの初期化プログラム!これらのルールを知っている場合は注意が必要です.----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------根本は最も基本的なOO原則です).では、小さなオブジェクト間のコラボレーションには構成が必要です(実際には「コラボレーション可能な構成」自体が私たちが望んでいる柔軟性です):例えばObserverモードにおけるsubjectとobserverのコラボレーションにはsubjectを調整する必要があります.RegistorObserver(observer)は、マルチメディアフレームDirectShowにおけるfilterGraphとvideoWindowの連携のように、filterGraphを調整する必要があるように構成する.SetVideoWindow(videoWindow)が構成して関数を構築するのは典型的な構成タイミングであり、例えばclass CMyWindow:public CWnd{private:CFIlterGraph filterGraph;publicCMyWindow(){filterGraph.SetVideoWindow(this);};付録--------------------------------------ついでに基礎知識をまとめます
表1
who
be called
一般関数
class::fun()
コンストラクタ
superclass::superclass() ==〉subclass::subclass()
こうぞうかんすう
subclass::~subclass() ==〉superclass::~superclass()
表2
who
where
be called
ノンダミー関数
everywhere
class::fun()
かそうかんすう
一般関数
obj.vfun()
かそうかんすう
コンストラクタ
class::vfun()
かそうかんすう
こうぞうかんすう
class::vfun()
明らかにしなければならないのは、【構造/解析/一般】と【虚/非虚】は完全に独立した分類である:●「構造/解析」であれば「直列(chaining)」●「虚関数」であれば「可能obj.vfun()」であれば「共に有効」であるが「干渉しない」例えば、仮想構造関数の場合、
class superclass
{
virtual ~superclass() { println("superclass::~superclass()") };
};
class subclass : public superclass
{
virtual ~subclass() { println("subclass::~subclass()") };
};
superclass  * super = new subclass();
delete super;
を実行した結果、
subclass::~subclass()
superclass::~superclass()
が印刷された.これはdelete superが実行された場合を意味する.時:●チャイニングコールですか?はい.解析関数だからです.[原句]チャイニングコールはどこから始まりますか?subclass::~subclass()==>superclass::~superclass()から、superclass*superの実際のオブジェクトのタイプがsubclassであるため.