2

コンパイル時間を最小限に抑えるために、可能な限り前方宣言を使用しようとしています。std :: vectorのようなものをメンバーオブジェクトとして使用しているクラスを前方宣言すると、次のことに気づきました(ここの例):

class myTypeA
class A
{
  A(){};
  ~A(){};
  std::vector<myTypeA > getTypeA();

}

次のエラーが発生します。

microsoft visual studio 9.0\vc\include\vector(1112) : error C2036: 'myTypeA *' : unknown size
1>        c:\program files\microsoft visual studio 9.0\vc\include\vector(1102) : while compiling class template member function 'bool std::vector<_Ty>::_Buy(unsigned int)'
1>        with
1>        [
1>            _Ty=myTypeA
1>        ]
1>        d:\cpp\A.h(15) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=myTypeA
1>        ]

#include "myTypeA.h"を使用すると、これは正常に機能します。なぜですか?

4

3 に答える 3

6

これは、コンパイラがベクトルに格納される型のサイズを知る必要があるためです。完全なクラス定義がなければ、これを知る方法はありません。

別の方法は、前方宣言型へのポインタを格納することですが、メモリの割り当てと割り当て解除を管理する必要があります。

3番目のオプションはshared_ptr、前方宣言された型に基づいて型を宣言し、これらをベクトルに格納することです。

于 2012-07-03T07:42:29.027 に答える
0

エラーが言うように

error C2036: 'myTypeA *' : unknown size

コンパイラは、前方宣言によってこのタイプのオブジェクトのサイズを認識しません。それはそれがどんなタイプであるかを伝えるだけです。コンパイラがこのタイプのオブジェクトのサイズを評価できるように、クラス定義を取り込むためのヘッダーを含める必要があります。

このSOの質問を参照してください

于 2012-07-03T08:17:58.163 に答える
-1

簡単な答えは、型上でテンプレートをインスタンス化するときはいつでも、標準は完全な定義を必要とするということです。それ以外の場合は未定義の動作です。このような制約を適用するコンパイラー(適切なオプションを使用してコンパイルする場合はg ++)は、コンパイラーに失敗します。他の人はそれを受け入れるかもしれません。(正式には未定義の動作ですが、実際には、コンパイルに失敗するか、期待どおりに機能します。)

について何も知る必要がないので、Microsoftがあなたが投稿したコードのビットをコンパイルできないことに少し驚いていますmyTypeA。メッセージは、関数を呼び出している場合に表示される可能性のあるもののように見えます。関数を呼び出す場合はmyTypeA、コンパイラーがコピーコンストラクターをインスタンス化する必要があるため、必ずの定義が必要になります。これは、含まれているのインスタンスをコピーすることを意味します myTypeA

于 2012-07-03T08:34:39.563 に答える