「More effecitve C++条項25:constructorとnon-member functionを虚化」読後感


More effective C++が手に入ってもうすぐ1年になりますが、買ったばかりの頃に一度見たことがありますが、レベルが低すぎて分からないものが多いので、この条項は読めないものの一つです.最近またこの本をひっくり返して、しっかりかじってください.
タイトルを見たときにconstructorを虚化すると、まず不思議なことに、コンストラクション関数が虚関数なのか、意味的にコンストラクション関数はオブジェクトを実例化するために使われ、コンパイル時の状態であり、コンストラクション関数が虚関数であれば、コンパイル時にコンパイラはどのコンストラクション関数を選ぶべきか分からず、馬鹿になる.疑問を持って、この章をもう一度見て、構造関数をどのように虚関数にしたのかを見てみましょう.
この章では、virtual constructorを説明するために、著者らはいくつかの例を挙げた.
例1:
コードは次のとおりです.
class NLComponent {   //

public:

...

};



class TextBlock: public NLComponent{ //           

public:

...

};



class Graphic: public NLComponent{ //           

public:

...

};



class NewsLetter { //             NLComponent     

public:

NewsLetter(istream& str);//NewsLetter    istream         ,   stream                 

...

private:

//  str     NLComponent   ,    ,          

static NLComponent* readComponent(istream &str);

list<NLComponent *> components;

};



NewsLetter::NewsLetter(istream &str)

{

    while(str)

    {

        components.push_back(readComponent(str));

    }

}

上記のコードから分かるように、NLComponentのConstructorは仮想化されていない.彼はreadComponentでistreamを読み取るだけで異なるタイプのコンポーネントを生成し、コンポーネントのポインタを返し、その後、ポインタをベースクラスポインタ(NLComponent*)タイプで格納し、後の呼び出しでマルチステートを実現することができる.これがVirtual Constructorである.
例2:virtual copy constructor
コード:
class NLComponent{ 

 public:

 //   virtual copy constructor

 virtual NLComponent *clone() const = 0;

};

class TextBlock:public NLComponent{ public: virtual TextBlock* clone() const { return new TextBlock(*this);} }; class Graphic:public NLComponent { public: virtual Graphic* clone() const {return new Graphic(*this);} };
NewsLetter{ public: NewsLetter(const NewsLetter& rhs);
private: list<NLComponent *> components; };
NewsLetter::NewsLetter(const NewsLetter& rhs) { for(list<NLComponent*>::const_iterator it = rhs.components.begin(); it != rhs.components.end(); ++it) { component.push_back((*it)->clone()); }
}

上記のコードから分かるように、cloneという虚関数により、NLPomponentを多態的にコピーすることができ、NLPomponentのコピー構造関数が深いコピーであっても浅いコピーであっても関係ない.cloneはそのコピー構造関数を呼び出し、実装ではないため、コピー構造関数の実装の詳細を遮断することができる.これからの拡張に備えて、いいですね.ははは.
virtual copy constructorは、「派生クラスがベースクラスの虚関数を再定義する場合、必ずしもベースクラスの虚関数と同じ戻りタイプを持つ必要はありません」を利用します.ベースクラスでは、cloneはbase classを指すポインタを返し、派生クラスではcloneは派生クラスを指すポインタを返します.これによりvirtual copy constuctorを実現できます.
私のレベルはまだ高くないので、認識がまだ不足しています.ありがとうございます.