8

http://msdn.microsoft.com/en-us/library/9ekhdcxs(v=vs.80).aspxによると、

C2079は、前方宣言がスコープ内にあるタイプのスタックでオブジェクトを宣言しようとした場合にも発生する可能性があります。

class A;

class B {
    A a;   // C2079
};

class A {};

考えられる解決策:

class A;

class C {};

class B {
   A * a;
   C c;
};
class A {};

私の質問は、次のような状況でこのエラーをどのように排除するかです。

class A;  // Object

class B   // Container
{
   public:
     typedef int SomeTypedef;
   private:
     A a;   // C2079
};

class A {
   void Foo(B::SomeTypedef);
};

AはBのtypedefを使用する必要があるため、Bを宣言する前にAを宣言することはできません。また、このエラーのために、Aの前にBを宣言することはできません。

考えられる解決策の1つは、スタック変数の代わりにAへのポインターを使用することですが、ポインターは必要ありません(この場合)。

別の解決策は、typedefを使用しないか、クラスB内に配置しないことです。しかし、B :: SomeTypedefがSomeTypedefよりも適切な名前であるように、それがBに属し、プロジェクトの名前空間を汚染したくない場合はどうでしょうか。

4

3 に答える 3

3

おそらくネストされたクラスがあなたの意図するものですが、あなたのデザインは疑わしいです:

class B {
   public:
     typedef int SomeTypedef;
   private:
     class A {
       void Foo(SomeTypedef);
     };
     A a;
};

そうでない場合、これはCRTPコードで一般的な別のクラスで解決することもできます。

template<typename T>
struct foo;

class A;
class B;

template<>
struct foo<B> {
  typedef int SomeTypedef;
};

class A {
   void Foo(foo<B>::SomeTypedef);
};

class B : foo<B> {
   private:
     A a;
};

または、別の名前空間を使用できます。

于 2012-04-27T17:56:55.733 に答える
3

もう1つのメソッドは、中間クラスとポインターを使用することです。これはより長くなりますが、機能します。

これはヘッダーファイルです(はい、「*。hpp」拡張子は標準ではありません):


ForwardClassExample.hpp

class ForwardClass {
public:
  virtual void DoSomething();
};

class ContainerClass {
   ForwardClass* Item;

   /* constructor */ ContainerClass();
   /* destructor */ ~ContainerClass();
};

class RealClass: ForwardClass {
  /* override */ virtual void DoSomething();
};

これは本文ファイルです:


ForwardClassExample.cpp

/* constructor */ ContainerClass::ContainerClass()
{
  // create reference to forwaded class item
  this.Item = new RealClass();
}

/* destructor */ ContainerClass::~ContainerClass()
{
  // deletereference to forwaded class item
  free this.Item();
}

void ForwardClass::DoSomething()
{
  // ...
}

void RealClass::DoSomething()
{
  // ...
}

ノート:

直接フィールドではなく、変数へのポインターの適用に慣れることをお勧めします。最初は難しいように見えるかもしれませんが、最終的にはより多くのことを実行できるようになります。

また、ある日、他のプログラミング言語で作業しなければならない場合に備えて、「参照」を使用する準備をします。

乾杯。

于 2012-04-27T18:41:49.133 に答える
1

デザインで必要な場所にtypedefを導入し、ユーザーにとって最も意味のある場所にエクスポートします。

class A
{
public:
   typedef int SomeTypedef;
   void Foo(SomeTypedef);
};

class B
{
public:
   typedef A::SomeTypedef SomeTypedef;
private:
   A a;
};
于 2012-04-27T21:07:40.400 に答える