Class name does not name a type in C++
I just started programming in C++, and I've tried to create 2 classes where one will contain the other.
File A.h
:
#ifndef _A_h
#define _A_h
class A{
开发者_开发技巧public:
A(int id);
private:
int _id;
B _b; // HERE I GET A COMPILATION ERROR: B does not name a type
};
#endif
File A.cpp
:
#include "A.h"
#include "B.h"
#include <cstdio>
A::A(int id): _id(id), _b(){
printf("hello\n the id is: %d\n", _id);
}
File B.h
:
#ifndef _B_h
#define _B_h
class B{
public:
B();
};
#endif
File B.cpp
:
#include "B.h"
#include <cstdio>
B::B(){
printf("this is hello from B\n");
}
I first compile the B class and then the A class, but then I get the error message:
A.h:9: error: ‘B’ does not name a type
How do I fix this problem?
The preprocessor inserts the contents of the files A.h
and B.h
exactly where the include
statement occurs (this is really just copy/paste). When the compiler then parses A.cpp
, it finds the declaration of class A
before it knows about class B
. This causes the error you see. There are two ways to solve this:
- Include
B.h
inA.h
. It is generally a good idea to include header files in the files where they are needed. If you rely on indirect inclusion though another header, or a special order of includes in the compilation unit (cpp-file), this will only confuse you and others as the project gets bigger. If you use member variable of type
B
in classA
, the compiler needs to know the exact and complete declaration ofB
, because it needs to create the memory-layout forA
. If, on the other hand, you were using a pointer or reference toB
, then a forward declaration would suffice, because the memory the compiler needs to reserve for a pointer or reference is independent of the class definition. This would look like this:class B; // forward declaration class A { public: A(int id); private: int _id; B & _b; };
This is very useful to avoid circular dependencies among headers.
I hope this helps.
error 'Class' does not name a type
Just in case someone does the same idiotic thing I did ... I was creating a small test program from scratch and I typed Class instead of class (with a small C). I didn't take any notice of the quotes in the error message and spent a little too long not understanding my problem.
My search for a solution brought me here so I guess the same could happen to someone else.
NOTE: Because people searching with the same keyword will land on this page, I am adding this answer which is not the cause for this compiler error in the above mentioned case.
I was facing this error when I had an enum
declared in some file which had one of the elements having the same symbol as my class name.
e.g. if I declare an enum = {A, B, C}
in some file which is included in another file where I declare an object of class A
.
This was throwing the same compiler error message mentioning that Class A does not name a type
. There was no circular dependency in my case.
So, be careful while naming classes and declaring enums (which might be visible, imported and used externally in other files) in C++.
You must first include B.h
from A.h
. B b
; makes no sense until you have included B.h
.
The problem is that you need to include B.h
in your A.h
file. The problem is that in the definition of A
, the compiler still doesn't know what B
is. You should include all the definitions of all the types you are using.
Include "B.h" in "A.h". That brings in the declaration of 'B' for the compiler while compiling 'A'.
The first bullet holds in the case of OP.
$3.4.1/7 -
"A name used in the definition of a class X outside of a member function body or nested class definition27) shall be declared in one of the following ways:
— before its use in class X or be a member of a base class of X (10.2), or
— if X is a nested class of class Y (9.7), before the definition of X in Y, or shall be a member of a base class of Y (this lookup applies in turn to Y’s enclosing classes, starting with the innermost enclosing class),28) or
— if X is a local class (9.8) or is a nested class of a local class, before the definition of class X in a block enclosing the definition of class X, or
— if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class or a nested class within a local class of a function that is a member of N, before the definition of class X in namespace N or in one of N’s enclosing namespaces."
when you define the class A, in A.h, you explicitely say that the class has a member B.
You MUST include "B.h" in "A.h"
Aren't you missing the #include "B.h" in A.h?
The solution to my problem today was slightly different that the other answers here.
In my case, the problem was caused by a missing close bracket (}
) at the end of one of the header files in the include chain.
Essentially, what was happening was that A
was including B
. Because B
was missing a }
somewhere in the file, the definitions in B
were not correctly found in A
.
At first I thought I have circular dependency and added the forward declaration B
. But then it started complaining about the fact that something in B
was an incomplete type. That's how I thought of double checking the files for syntax errors.
Try to move all includes outside namespace.
//Error
namespace U2 {
#include <Head.h>
#include <LifeDiode.h>
}
//Solution
#include <Head.h>
#include <LifeDiode.h>
namespace U2 {
}
Not the answer, but for me the thing was that I forgot to add the std::
before the potential type to properly use it.
It actually happend to me because I mistakenly named the source file "something.c" instead of "something.cpp". I hope this helps someone who has the same error.
精彩评论