1

Gotw 80には、次の例が含まれています。

  // Example 1
  //
  #include <string>
  using namespace std;

  class A
  {
  public:
    A( const string& s ) { /* ... */ }
    string f() { return "hello, world"; }
  };

  class B : public A
  {
  public:
    B() : A( s = f() ) {}
  private:
    string s;
  };

  int main()
  {
    B b;
  }

この記事では、s = f()オブジェクトの有効期間と作成順序が原因で、行が正しくない理由について説明します。この記事では、当時、エラーはコンパイラによって検出されなかったと述べています。

ただし、初期化の順序とオブジェクトの有効期間の問題を無視するとs = f()、コンストラクターのパラメーターリストで構文的に合法になる方法がわかりません-パラメーターリストでメンバーを初期化しようとしているようです(またはおそらくデフォルトを宣言しています)価値)。この構文が何をしようとしているのか、誰か説明できますか?

4

2 に答える 2

3

を呼び出しf()て結果を代入する意図があったようB::sです。その後、継承されたコンストラクターを呼び出すときに、その割り当ての結果 (つまりs) が実際のパラメーターとして使用されます。A

構文的に有効です。sその式を非メンバー変数に置き換えると、g ++ は問題なく受け入れます。コンストラクター呼び出しではなく、通常の関数呼び出しで同様の構文がより頻繁に使用される場合があります。

于 2011-10-31T21:33:05.423 に答える
1

構文的には合法です...引数をとるコンストラクターを持つ基本クラスがある場合、もちろん任意の式をパラメーターとして渡すことができます。

strut A {
    A(int) {}
};

struct B : A {
    B() : A( any expression that returns an int ) {}
};

問題は、例の式を評価するとき、オブジェクトがまだ完全に構築されたAインスタンスでさえないため、コードが 2 つの明確な理由で無効になることです。

  1. A非インスタンスのメソッドを呼び出します (コンストラクターがまだ開始されていません):f()呼び出しは不正です。
  2. 初期化されていないメンバーへの代入:s=...不正です。
于 2011-10-31T21:47:55.173 に答える