or.nomore
or.nomore

Reputation: 925

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?

Upvotes: 50

Views: 217157

Answers (13)

Pond-nj
Pond-nj

Reputation: 45

Another possible scenarios: "Circular includes" of header files.

A.h

#pragma once
#include "B.h"

Class A{
    ...
    B& b;
};

B.h

#pragma once
#include "A.h"

Class B{
    ...
};

Upvotes: 0

Caio V.
Caio V.

Reputation: 315

Not the answer, but for me the thing was that I forgot to add the std:: before the potential type to properly use it.

Upvotes: 0

Jarosław Ośka
Jarosław Ośka

Reputation: 11

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 {

}

Upvotes: 0

user3499516
user3499516

Reputation: 1

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.

Upvotes: -3

dyno8426
dyno8426

Reputation: 1249

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++.

Upvotes: 11

Maghoumi
Maghoumi

Reputation: 3380

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.

Upvotes: 1

Ivan
Ivan

Reputation: 4753

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.

Upvotes: 16

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76788

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:

  1. Include B.h in A.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.
  2. If you use member variable of type B in class A, the compiler needs to know the exact and complete declaration of B, because it needs to create the memory-layout for A. If, on the other hand, you were using a pointer or reference to B, 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.

Upvotes: 67

Chubsdad
Chubsdad

Reputation: 25497

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."

Upvotes: 2

Nuno Ramiro
Nuno Ramiro

Reputation: 1756

Aren't you missing the #include "B.h" in A.h?

Upvotes: 1

Stephane Rolland
Stephane Rolland

Reputation: 39906

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"

Upvotes: 1

Amir Rachum
Amir Rachum

Reputation: 79635

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.

Upvotes: 2

Puppy
Puppy

Reputation: 146930

You must first include B.h from A.h. B b; makes no sense until you have included B.h.

Upvotes: 3

Related Questions