2016-09-10 7 views
1

次のコードでDemo1とDemo2に違いはありますか?"my_constructor:variable(x)"と "this.variable = x"のコンストラクタの違いはありますか?

#include <iostream> 

class Base {}; 

class Demo1 : public Base { 
public: 
    Demo1() : instance_variable(5) { 

    } 

    int instance_variable; 
}; 

class Demo2 : public Base { 
public: 
    Demo2() { 
     this->instance_variable = 5; 
    } 

    int instance_variable; 
}; 

int main(int argc, char **argv) 
{  
    Demo1 a;  
    Demo2 b; 

    std::cout << "a.instance_variable: " << a.instance_variable << std::endl; 
    std::cout << "b.instance_variable: " << b.instance_variable << std::endl; 

    return 0; 
} 

私は私が今読んでいる本の中で最初の表記を見て、私は2つが等価であるかDEMO1は微妙な違いを持っ​​ている場合、私が知っておくべきかわかりません。

私はJava/JavaScriptのバックグラウンドから来ているので、2番目のほうがはるかに読みやすいので、コードの意味を変えずに "Demo1"を "Demo2"に置き換えることができるのは不思議です。

また、「constructor:field(x){}」という表現は何ですか?

+0

私はあなたがこれを読むことをお勧め:http://stackoverflow.com/questions/6822422/c-where-to-initialize-variables-in-constructor – Meraj99

+1

初期化子リストそれだ –

+0

@SauravSahuの感謝を!しかしそれと同等ですか?私はそれを受け入れることができるように答えを投稿してください。 – Dmitry

答えて

1

あなたは(あなたが言ったように、あなたが持っている)、プログラミングの背景を持っている場合は、initializing変数に値といくつかの変数に値のassignment間の差を十分に認識する必要があります。

Demo1は(instance_variableDemo() : instance_variable(5)メンバー初期化子リストを初期化されている)が、Demo2は私がもしわからないinstance_variable

から値を割り当てるある変数の初期化を使用しています2つは同等か、またはDemo1に微妙な違いがある場合は、私が知っておく必要があります。

いいえ2つは同等ではありません。

  • Demo1instance_variableを初期化され、それはコピーコンストラクタが呼び出されることを意味し(場合、instance_variableがオブジェクトである場合)。それが初期化された後
  • しかしDemo2変数に値を代入されます(デフォルトコンストラクタが呼ばれてきた、そして今operator=は値をコピーするために呼び出されます)と呼ばれる表現constructor:field(x){}で何も

、 ?

member initializer listと呼ばれています。

EDIT

メンバー初期化子リストはオブジェクトのみを初期化するときの違いになりますが、プリミティブの場合には、両方の方法(Demo1Demo2)、彼らはほとんど同じです。

そして、あなたが知っておくべきことを別の事があります、あなたは初期化するために、メンバー初期化子リストを使用する必要がありますことを、次のとおりです。

  • のconstデータメンバ
  • メンバー参照変数
  • デフォルトのコンストラクタを持たないメンバ変数(あるクラスのオブジェクト)を初期化します。
  • と、パラメーターを基本クラスのコンストラクターに渡すとき。
+0

インスタンス変数がプリミティブではなくオブジェクトである場合、それらの主な違いがありますか?彼らはプリミティブの場合には同等ですか(破壊されていない、それは単に範囲外になります)? – Dmitry

+1

余分なオーバーヘッドはオブジェクトの場合に発生します(yes)。しかし、プリミティブの場合、ほとんど同じです。 –

6

違いがあります。その結果、最初のアプローチであるコンストラクタの初期化子の構文がより良いと考えられます。 DEMO2で

、すべてがデフォルト初期化してからオペレータを取得=新しい価値を与えるために使用されます。 instance_variableは単なるint型なので、これは問題ではありません。しかし、それは問題になる場合:

  • デフォルトコンストラクタ、演算子=、またはその両方が計算コストが高い
  • デフォルトのコンストラクタには存在しない
  • 変数は、演算子を使用しないことができることを意味し、constのか、参照であります=値
  • を変更するには、変数は、あなたが実際に割り当てが続くデフォルトコンストラクタからより引数を取るコンストラクタから別の結果を得るように、反直感的に書き込まれているクラスのインスタンスです。そのようなクラスは存在してはいけませんが、そうではないというわけではありません。

DEMO1の道は時々速くなる(遅く決して)とDEMO2の方法がない場合に動作するので、それは手法を好んであります。他の言語の人には珍しいかもしれませんが、それはあなたのコンストラクタを書くべき方法です。

0

Demo1はmember initializer listを使用します。引数5を使用してinstance_variableのコンストラクタを呼び出します。

Demo2は、のinstance_variableを引数5で使用します。あなたのケースでは

instance_variableintであることから、違いはありません。ただし、instance_variableが、初期化とコピー割り当てで異なる動作をするクラスのオブジェクトの場合は、違いがあります。

0
  1. これは、「メンバーの初期化」のための
  2. と呼ばれ、それは違いはありませんintです。複合オブジェクトの場合、メンバーinitは、デフォルトのcotrを呼び出してから手動でプロパティを設定するのではなく、必要なparamsでメンバーのc-torを一度呼び出します。
0

使用してメンバー初期化子リスト(デモ1):

A.)変数のコピーコンストラクタはinstance_variable(value)と呼ばれています。 B.)デストラクタは、valueが範囲外になると呼び出されます。コンストラクタブロック内

copy constructor + destructor call 

初期化(デモ2): A.)変数のコピーコンストラクタはinstance_variable(value)と呼ばれています。 B.)コンストラクタ本体内の代入演算子の呼び出し。 C.)デストラクタはvalueが範囲外になると呼び出されます。

constructor + one addition assignment operator call(for complex and Non-PODs) + destructor 

この割り当てペナルティは、初期化するための多くのそのような複雑なオブジェクトがあるだろう「本物」のアプリケーションではるかになります。 int割り当てを行っているので、違いはありません。

Read more.

関連する問題