2

私が知る限り、オブジェクトの戻り値の型を持つ関数を定義するとき、クラスは次のような前方宣言状態にあるだけです。

class A; 

// Aを不完全な型として設定する前方宣言

A foo(){...} 

//エラー: A は不完全な型です。そのオブジェクトへのポインターまたは参照の戻り値の型がある場合、正常に動作することがわかっています。

しかし、クラスとして戻り値の型を持つメソッドを定義すると、次のようになります。

class B{
  public:
    B foo(){...}
}

それは完全にうまく機能します。

クラスの定義内でメソッドを定義するとき、クラスはまだ不完全な型だと思います。そのため、前者と同様のエラーが表示されると思いますが、そうではありませんでした。誰かが理由を知っていますか?

ここで助けを求める前に、かなりの時間を探しました。(私は英語が苦手なので、私の説明はあなたを混乱させるかもしれません。申し訳ありません。)

4

2 に答える 2

3

クラス内でメソッドを定義する場合、クラスは完全な型であるかのように扱われます。そうしないと、インライン メソッドを定義できません。また、クラス A が不完全な型の場合、奇妙に繰り返されるテンプレート パターンも機能しません。次のコードを検討してください。

template <typename T> struct base {};

struct derived : base<derived> {};  // We can use derived here
                                    // without any "incomplete type"
                                    // errors.

言い換えれば、それは言語が機能する方法です。

編集: この動作について言及している C++ 標準の関連セクションについては、以下の Mike Seymour を参照してください。

于 2013-03-18T13:35:39.160 に答える
2

ほとんどの場合、不完全な型を返す関数を定義できなかったのは正しいことです。ただし、ルールには、独自の定義内でクラスを使用できるようにするためのいくつかの例外があります。

C ++ 11 8.3.5 / 9で指定されているように、その時点では不完全でBあっても、そのメンバー関数の1つに対しての戻り型を宣言することは問題ありません。B

関数定義がそのクラスのメンバー仕様内にネストされていない限り、パラメーターの型または関数定義の戻り型は、不完全なクラス型(おそらくcv修飾)であってはなりません。

B関数本体に返すタイプのオブジェクトをインスタンス化することも問題ありません。クラス定義内では、C ++ 11 9.2 / 2で指定されているように、クラスは関数本体を含むさまざまなコンテキストで完全であると見なされます。

クラスメンバー仕様内では、クラスは、関数本体、デフォルト引数、例外仕様、および非静的データメンバー(ネストされたクラスのようなものを含む)のbrace-or-equal-initializers内で完全であると見なされます。それ以外の場合は、独自のクラス メンバー仕様内で不完全であると見なされます。

于 2013-03-18T14:33:17.157 に答える