Kuan
Kuan

Reputation: 11389

Forward declaration between files

All:

I have two files:

main.cpp

#include <iostream>

using namespace std;

class A;

int main(){
    A a;
    a.disp();

    return 0;
}

and A.cpp

#include <iostream>
using namespace std;

class A{

    public:
    A(){}
    void disp(){ cout<<"this is A disp()"<<endl;}
};

I wonder why when I compile this two files, it told me that:

main.cpp: In function ‘int main()’: main.cpp:8:4: error: aggregate ‘A a’ has incomplete type and cannot be defined

I think it because I do not understand how to use forward declaration, so can someone tell me how to do this?

BTW, I know the header file way to do this, but I just want to figure out in this forward declare way.

best,

Upvotes: 4

Views: 258

Answers (3)

Emile Vrijdags
Emile Vrijdags

Reputation: 1578

When you only use a pointer to a class in another class declaration, only a forward declaration is needed. This means that only the class' name is known at that point but not the definition of its members, or its size. The Type is incomplete.

When you actually want to use a membervariable or memberfunction, or when the class gets instantiated by an automatic variable or using new(), or the type gets used to declare a member in another class. The normal class declaration must done before that point, and the class definition must be known at that point so there must have been an include of the class definition in the same translation unit.

One example where it is useful: forward declaration usually gets used to circumvent circular class dependancy/inclusion. Where one class has members of a second class, that also has members of the first class. When one includes the other, and the other includes the one, problems occur. When you only use a forward declaration and postpone the actual inclusion to a later point, there is no circular inclusion anymore.

Upvotes: 1

juanchopanza
juanchopanza

Reputation: 227370

main needs to know the size of class A, and that it has a member function disp(). For this reason, must have access to the class declaration. Put it in a file A.h (with include guards and no using namespace std), and include that in main.cpp.

file A.h

#ifndef A_H_
#define A_H_

#include <iostream>

class A
{
    public:
    A(){}
    void disp() const { 
      std::cout<<"this is A disp()"<<std::endl;
    }
};

#endif

main.cpp:

#include "A.h"

int main() { .... }

Note that you could decide to put the implementation of void A::disp() in an A.cpp file instead of in the header.

Upvotes: 3

Dave
Dave

Reputation: 46249

Since you are only declaring it as a class (i.e. you don't tell the compiler what the class contains), it is unable to create memory for it (it doesn't know how big it needs to be).

What you can do is define pointers to an A class:

int main(){
    A *a;
    // a->disp() is still invalid

    return 0;
}

but you won't be able to do anything with it.

This is exactly what headers are for!

A.h:

class A{
public:
    A(){}
    void disp();
};

A.cpp:

#include "A.h"
void A::disp(){
    cout<<"this is A disp()"<<endl;
}

After including a.h in a file, you will be able to create & use it as you would expect.

Upvotes: 6

Related Questions