简体   繁体   English

如果前向声明不够,如何避免“'标识符'使用未定义的类/结构/联合'名称'”错误?

[英]How to avoid “'identifier' uses undefined class/struct/union 'name'” error when forward declaration is not enough?

According to http://msdn.microsoft.com/en-us/library/9ekhdcxs(v=vs.80).aspx , 根据http://msdn.microsoft.com/en-us/library/9ekhdcxs(v=vs.80).aspx

C2079 can also occur if you attempt to declare an object on the stack of a type whose forward declaration is only in scope. 如果您尝试在其前向声明仅在范围内的类型的堆栈上声明对象,也会发生C2079。

 class A; class B { A a; // C2079 }; class A {}; 

Possible resolution: 可能的决议:

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

My question is how do I eliminate this error when I have the following situation: 我的问题是当我遇到以下情况时如何消除此错误:

class A;  // Object

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

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

I can't declare A before declaring B because A needs to use B's typedef, and I can't declare B before A because of this error. 在声明B之前我无法声明A,因为A需要使用B的typedef,并且由于此错误,我无法在A之前声明B.

One possible solution is to use a pointer to A instead of a stack variable, but I don't want a pointer (in this case). 一种可能的解决方案是使用指向A而不是堆栈变量的指针,但我不想要指针(在本例中)。

Another solution is to not use typedef, or not to put it inside class B. But what if it belongs in B and I want not to pollute my project's namespace, as in B::SomeTypedef is a more appropriate name than SomeTypedef? 另一个解决方案是不使用typedef,或者不将它放在B类中。但是如果它属于B并且我不想污染我的项目的命名空间,如B :: SomeTypedef是一个比SomeTypedef更合适的名称呢?

Your design is questionable, although perhaps nested classes is what you intend: 你的设计是有问题的,虽然你想要的嵌套类可能是:

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

If not, this can also be solved with another class which is common in CRTP code. 如果没有,这也可以用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;
};

Or you can use another namespace. 或者您可以使用其他命名空间。

Another method is use an intermediate class, plus pointers, its more long, but, it works: 另一种方法是使用中间类,加上指针,它更长,但是,它的工作原理是:

This is header file, ( yes I know, "*.hpp" extension is not standard ): 这是头文件,(是的我知道,“* .hpp”扩展名不是标准的):


ForwardClassExample.hpp ForwardClassExample.hpp

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

class ContainerClass {
   ForwardClass* Item;

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

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

This is body file: 这是正文文件:


ForwardClassExample.cpp 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()
{
  // ...
}

Note: 注意:

I suggest to get used to apply pointers to variables, instead of direct fields, its may looks more difficult, at start, but, eventually allows to do more stuff. 我建议习惯将指针应用于变量,而不是直接字段,它可能看起来更难,一开始,但最终允许做更多的东西。

It also prepare you to use "references" in case, one day you have to work with other programming languages. 它还准备你使用“引用”,以防有一天你必须使用其他编程语言。

Cheers. 干杯。

Introduce the typedef where your design requires it, and then export it to wherever it makes the most sense for your user. 在您的设计需要的地方引入typedef,然后将其导出到对您的用户最有意义的地方。

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

class B
{
public:
   typedef A::SomeTypedef SomeTypedef;
private:
   A a;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM