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);
};

我不能在声明B之前声明A,因为A需要使用B的typedef,并且因为这个错误我不能在A之前声明B。

一种可能的解决方案是使用指向 A 的指针而不是堆栈变量,但我不想要指针(在这种情况下)。

另一种解决方案是不使用 typedef,或者不将其放在类 B 中。但是如果它属于 B 并且我不想污染我的项目的命名空间,因为 B::SomeTypedef 是比 SomeTypedef 更合适的名称怎么办?

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

另一种方法是使用中间类,加上指针,它更长,但是,它可以工作:

这是头文件,(是的,我知道,“*.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 回答