2016-10-08 4 views
3
struct SalesData { 

    SalesData() = default; 
    SalesData(const string&s) : bookNo(s) {} 

    string bookNo; 
    unsigned copies_sold = 0; 
    double revenue = 0; 
}; 

デフォルトのコンストラクタについて議論していますが、プライマーは上記のコードのようにコンストラクタをデフォルトにすることができます。そのキーワードは、クラス内の宣言、またはクラス外の定義とともに現れます。 コンパイラがクラス内イニシャライザを使用できない場合は、2番目のコンストラクタと同じようにイニシャライザリストを使用できます。C++プライマーは、 "=デフォルト"のコンストラクタにイニシャライザリストを使用できると述べています。

しかし、形式は何ですか?

まず、私は直接初期化リストを使用しようとしました:

SalesData() = default:bookNo(""), copies_sold(1), revenue(2){}; 

をしかし、それは動作しないことができ、コンパイラは「デフォルト」のaferコロンがあってはならないと言います。

は、その後、私はクラスで「=デフォルト」でコンストラクタを宣言し、初期化子リストを使用せず、外部にそれを定義しようとしました:

struct SalesData { 
    SalesData() = default; 
    /*...*/} 

SalesData::SalesData() { 
    bookNo = ""; 
    copies_sold + 0; 
    revenue = 0; 
} 

コンパイラは、それが再定義のエラーだと言います。 はその後、私は大丈夫になっているプラ​​イマーは言う、外部のキーワードを移動:

struct SalesData { 
    SalesData(); 
    /*...*/} 

SalesData::SalesData()=default { 
    bookNo = ""; 
    copies_sold + 0; 
    revenue = 0; 
} 

それはまだ失敗し、コンパイラは、「デフォルト」behineセミコロンがなければならないと述べました。

私は同様の質問についてはGoogleで検索しましたが、何も見つかりませんでした。

  1. "=デフォルト"とイニシャライザのリストはどのように連携できますか?

  2. 「=デフォルト」をクラス本体の外で使うべきですか?

+1

初期化子リストがある場合、これはデフォルトのバージョンではなく、ユーザー定義のコンストラクタです。だから '= default'をスキップするだけです。 –

+1

'= default'は、コンパイラにコンストラクタ/代入を生成させたいときに指定します。これはあなたがそれの定義を持つことができないことを意味します。これはデフォルト(より多くの単語が必要)にのみ適用され、initializer_listを持つユーザー定義のコンストラクタではなく、コンストラクタとそれぞれの割り当てをコピーして移動します。 – DeiDei

答えて

2

特定の状況では、コンパイラは自動的にデフォルトのctorのような特殊な関数を生成します。 =defaultは、自動的には発生しない状況でも関数を生成するようにコンパイラに明示的に指示する方法です。

ポイントは次のとおりです。あなたがどちらかはあなた=defaultにそれをいつもとしての機能を自分で実装しますか。同じ機能のために両方を行うことはできません。コンパイラが生成するものに影響を及ぼす唯一の方法は、あなたのようなデフォルトイニシャライザによるものですdouble revenue = 0;

デフォルトのctor、copy ctor、copy assignment、move ctor、move assignmentおよびdestructorではコンパイラによって生成された実装が利用できます。詳細はthis answerを参照してください。 SalesData(const string&)はこれらのどちらでもないので、=defaultにすることはできません。

+0

ありがとう、今、私はその定義を学び=デフォルトは一緒に働くことはできません。しかし、C++の初級5thは次のように述べています。「...新しい標準では、デフォルトの動作が必要な場合、パラメータリストの後に= defaultを書くことによって、コンストラクタを生成するようにコンパイラに依頼することができます。クラス本体の中の宣言やクラス本体の外側の定義に現れる** ... "だから、宣言と定義についての言葉はどういう意味だろうか? – Dardai

+0

@Dardaiこれらの場所のいずれかに '= default'を置くことができます。しかし、 '= default'を使わない宣言と' = default'を用いた定義があります。 (また、セマンティクスの違いがあり、アウトオブラインの状況は* user-provided *としてカウントされません) –

3

機能が=default宣言されている場合は、(コンストラクタ)初期化子リストを提供し、また、関数本体はできません。

本が間違っているか、本の内容が間違っています。

+0

OPは、おそらく集合初期化を参照していることに注意してください。これは、明示的にデフォルトのコンストラクタに許可され、初期化子リスト構文を使用します。 – DeiDei

+0

ありがとう、今私はその定義を学ぶ=デフォルトは一緒に動作することはできません。しかし、C++の初級5thは次のように述べています。「...新しい標準では、デフォルトの動作が必要な場合、パラメータリストの後に= defaultを書くことによって、コンストラクタを生成するようにコンパイラに依頼することができます。クラス本体の中の宣言やクラス本体の外側の定義に現れる** ... "だから、宣言と定義についての言葉はどういう意味だろうか? – Dardai

+0

@Dardai 'SalesData()= default;'のようなクラスの中か、 'SalesData :: SalesData()= default;'のようなクラスの中に書くことができると思っています。 – songyuanyao

1

追加情報

クラスにコンストラクタを指定しない場合、コンパイラはデフォルトのコンストラクタを生成します。このコンストラクタは、すべてのメンバーをデフォルトの(空の)コンストラクタで初期化します(コンストラクタが存在しない場合はコンパイルエラーになります)。

デフォルト以外のコンストラクタを指定すると、コンパイラはデフォルトのコンストラクタを自動的に生成しません。ここではいくつかの詳細を見つけることができます:

Conditions for automatic generation of default/copy/move ctor and copy/move assignment operator?

=defaultキーワードは、明示的に(すでに別のものを指定した場合にも)、デフォルトのボディにデフォルトコンストラクタを生成するようにコンパイラーに頼むことを意味します。つまり、このコンストラクタの本体は、あなたではなくコンパイラによって作成されます。これは、定義しようとするとコンパイルエラーが発生する理由です。

=defaultキーワードは、デストラクタでも使用できます。

関連する問題