2012-02-25 6 views
2

クラスを設計する際に、コンストラクターに入れるものとInitに入れるものを混同します。だからあなたはこのことについてあなたの意見を述べてください。以下の私の質問を見つけてください。クラスを設計する際に、コンストラクターとInit関数にはどうすればよいでしょうか

  1. 万一クラスは別のInit関数がありますか?
  2. 「はい」の場合、クラスのクラスおよびInit関数のコンストラクタに入る必要があります。

私が理解しているように、私は一般的には(常に遅延初期化のための)Init関数を持つ傾向があります。例えば、私がConnectionPoolクラスを設計しなければならない場合、私はこれのようなものになります。

class ConnectionPool 
{ 
    string _host; 
    bool _isInit; //For separate Init, we need this 

    public: 
    ConnectionPool(string host) 
     :_host(host), 
     _isInit(false) 
    {} 
    void Init(); 
    bool isInit(){return _isInit;} 
} 

//This will actually make connections 
ConnectionPool::Init() 
{ 
    //Create few connections 
    //if successful 
    _isInit=true; 
} 
int main() 
{ 
    ConnectionPool cp("host"); 

    //Few other init & wait for request 
    //Now I have the request 
    if(cp.isInit() == false) 
     cp.Init(); 
} 

しかし最近、私は別のInit機能を持つことに抵抗することはできません。だから、良いことが何であるか教えてください。

+2

これはあなた次第です。オブジェクトが初期化されていない状態にあることは理にかなっていますか?その後、init関数が適切です。そうでない場合は、コンストラクタ内のすべてを持つことができます。 'std :: fstream'のようなものは初期化されたものと初期化されていないものの両方を提供しています。 –

+1

広く使われているC++のイディオムは[RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)です。アイデアは、独立したinitメソッドを持たずに、コンストラクタ内のすべてのリソース取得を行うことです。 – dasblinkenlight

答えて

7

通常init機能はプライベートであり、ちょうどcontructorsで使用されています。これは、さまざまなコンストラクタで同じ共通コードを必要とせず、したがって、膨らみとエラーをコードする傾向が少なくなるようにしています。

4

一般に、initスタイルの関数を持つ唯一の理由は、複数のコンストラクタのコードを因数分解することです。それはあなたがそれを必要としているときで、それには何があるべきかを意味します。

+0

oh。私は異なる方法でInitを使用しています。私の主な機能を見てください。 ConnectionPoolオブジェクトを初期化されていない状態のままにしておくと、それは良くないと思います。 –

0

万一クラスは別のInit関数がありますか?

いいえ、コンストラクタは、初期の目的を果たします。

「はい」の場合は、クラスのクラスとInit関数のコンストラクタに入る必要があります。

オブジェクトが完全にコンストラクタで初期化する必要があります。

+0

それはいつでも最善の方法ではありません。 KerrekSBのコメントが実際にこの点に当たっています。 –

+1

コンストラクタが複数ある場合、クラスには別々のInit関数が必要です。これはコピーコードを避けるためです。 – Lucian

1

主な違いは、あなたののinit機能は、あなたのクラスに追加するだけで通常の関数であるのに対し、コンストラクタは、クラスのインスタンスが作成されたときに自動的に呼び出される特殊な関数であることです。

ほとんどのクラスは、単純にすべての初期化を行い、コンストラクタを持っている - これは、可能な限り最高のものです。通常、別個のinit関数は、ネットワーク接続を開くなど、失敗したり例外をスローする操作がある場合にのみ便利です。

たとえば、ネットワーククライアントを実装するクラスは、デフォルト値にそのすべてのメンバーを初期化し、コンストラクタで、必要なバッファを割り当て、そして実際に開くように呼ばれる別ののinit機能を提供するかもしれませんサーバーへの接続。呼び出し元は常にオブジェクトを正常に構築できますが、initの呼び出しの回りで例外/エラー処理を行う必要があります。

0

適切な例外処理を使用すると、通常は安全にコンストラクタに初期化を置くことができます。例外的なエラーが発生した場合は、クラスを構築できなかったことを呼び出し側のコードに知らせる例外をスローすることができます。

関連する問題