How to avoid "Identifier" uses the undefined class / struct / union 'name' "error when an opaque declaration is not enough?

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

C2079 can also occur if you are trying to declare an object on a type stack whose direct declaration applies only to a scope.

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 to fix this error if 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 cannot declare A before declaring B, because A needs to use B typedef, and I cannot declare B before A because of this error.

One possible solution is to use a pointer to A instead of a stack variable, but I don't need a pointer (in this case).

Another solution is to not use typedef or put it in class B. But what if it belongs to B and I don’t want to pollute the project namespace, as in B :: SomeTypedef is a more suitable name than SomeTypedef

+7
source share
3 answers

Your design is dubious, although perhaps nested classes are what you intend:

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

If not, this can also be resolved by another class that is common in CRTP code.

 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 a different namespace.

+2
source

Another method is to use an intermediate class, plus pointers longer, but it works:

This is the header file (yes, I know, the extension "* .hpp" is not standard):


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 the body file:


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 getting used to applying pointers to variables instead of direct fields, it may look more complicated, but in the end it allows you to do more things.

It will also prepare you for the use of "links" in the case when you have to work with other programming languages.

Greetings.

+3
source

Enter a typedef where its design is required, and then export it to where it makes the most sense to your user.

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

All Articles