1

コンパイラはこのクラスのすべての要素をゼロで初期化するため、値クラスにはデフォルトのコンストラクターがないことを知っています。しかし、配列は値クラスにあり、初期化されていません:

value class c_LocationVal
{
public:
  double x, y, z;
  c_LocationVal(double i_x, double i_y, double i_z) {x = i_x; y = i_y; z = i_z;}
};

typedef cli::array<c_LocationVal> arrloc;

value class c_Managed
{
public:
  arrloc^ m_alocTest;

  //c_Managed() { m_alocTest = gcnew arrloc(3); }  --> not permitted

  double funcManaged ()
  {
    return m_alocTest[0].x;  --> error: Object reference not set to an instance of an object
  }
};

私はチートして使用することができました:

c_Managed(int i) { m_alocTest = gcnew arrloc(3); }

しかし、別の解決策があるはずです。
誰かがこれを解決する方法を教えてもらえますか?

4

3 に答える 3

2

CLR は、メソッド内のコードのみをサポートします。コンパイラは、必要に応じてコンストラクターを作成し、式のコードをコンストラクターに移動することで、メンバー初期化式の動作をエミュレートします。

これは、これが許可されていない理由を説明しています。式にはパラメーターなしのコンストラクターが必要であり、値の型に対しては正当ではありません。

確かに、あなたのトリックはうまくいきます。ただし、一般に、C++/CLI コードを作成するときは、C++ の仮定を少し調整する必要があります。C++ では、構造体とクラスの間に実質的な違いはありません。しかし、マネージ コードではそうはいきません。非常に単純な型に対してのみ値クラスを使用してください。初期化が必要な場合は、選択がref クラスに大きく影響します。配列を持つ値型と同様に、通常、それを事故なく機能させるにはディープ コピーが必要です。C++/CLI のヒープを恐れることはありません。非常に高速です。

于 2013-07-19T13:17:09.460 に答える
1

値クラスは常に「null/0」で初期化されます。そのため、値クラスのマネージド参照も常に "null" に初期化されます。特別な初期化が必要な場合は、解決策しかありません。指摘していたのは、値クラスを正しく「初期化」するためのいくつかのパラメーターを持つ特別なコンストラクターを作成する必要があるということです。

問題は、マネージ参照を含む値クラスが本当に必要ですか? ということです。通常、これもref class.

また、値クラスをコピーするとどうなりますか? 参照はどうなりますか?それも直接コピーされます!これは意図したものですか?値クラスの目標は、「本物の」コピーを提供することです! あなたの場合、「完全にコピー」されません...

value classデータストレージに最適なソリューションであるかどうかを再考してください...

于 2013-07-19T13:07:45.890 に答える