Problem with including .h and .cpp files

N

none

I have this class:


// header file
#ifndef A_H
#define A_H

class A {
public:
A();
};

#endif // A_H


// .cpp file
#ifndef A_CPP
#define A_CPP
#include "A.h"

A::A() {
}

#endif // A_CPP






When I create the class like:


A a;



I get the error:

undefined reference to `A::A()'

On solution to the problem is to include A.cpp at the end of A.h like:


// header file
#ifndef A_H
#define A_H

class A {
public:
A();
};

#include "A.cpp"

#endif // A_H



But is it good practice to include .cpp files at the end of .h file?

I have seen this done in various large CMake public projects like ITK but why is this convention used?
 
I

Ian Collins

none said:
I have this class:

// header file
#ifndef A_H
#define A_H

class A {
public:
A();
};

#endif // A_H

// .cpp file
#ifndef A_CPP
#define A_CPP

Include guards are unnecessary in source files.
#include "A.h"

A::A() {
}

When I create the class like:

A a;

I get the error:

undefined reference to `A::A()'

On solution to the problem is to include A.cpp at the end of A.h like:

Generally a very bad idea, unless you are writing templates with a
compiler that doesn't have lookup rules for definition files.

You should learn how to link separate compilation units and build
libraries on your platform.
 
J

John H.

none wrote:
Include guards are unnecessary in source files.

Generally a very bad idea, unless you are writing templates with a
compiler that doesn't have lookup rules for definition files.

You should learn how to link separate compilation units and build
libraries on your platform.

Ian is correct.
The normal design is:
But is it good practice to include .cpp files at the end of .h file?

Ian is correct. This is not good practice.

a.h:
#ifndef A_H
#define A_H
class A
{
public:
A();
};
#endif


a.cpp:
#include "a.h"
A::A() { }


main.cpp:
#include "a.h"
int main()
{
A a;
return 0;
}


So you were pretty close. Don't use #ifdef A_CPP in the .cpp file.
Don't #include the .cpp into the header. Also I couldn't tell from
what you posted, but there error message you got would be one I would
expect if I forgot the line #include "a.h" in the same file where I
try to create an A object (main.cpp in my example).

Basically what #include is doing is saying "take the source in this
other file and paste it into this file". What the #ifndefs are doing
(these are called "include guards"), is making sure the same code
doesn't get pasted multiple times into the same file. This important
when projects get bigger and you could be using the same class in
multiple files, etc.

Finally, you need to make sure you are building and linking things
correctly. If you are working in an IDE, this is mostly done
automatically. Just make sure the .cpp files are added to your
project. Having the .h files is usually just a convenience. Once you
add them to your project, you tell the compiler to "make an object
file for this .cpp file". Then when you say build, it makes all the
object files and then links them together to make an executable. The
reason the .h files are not strictly necessary to be added to a
project is because you will be #including them into the .cpp files
already (they get "pasted" in), so the compiler learns about them that
way.
If you are using a command line to compile, you need compile all
the .cpp files into object files. Then link all the object files into
an executable.
 
M

Michael Tsang

wrote:
I have this class:


// header file
#ifndef A_H
#define A_H

class A {
public:
A();
};

#endif // A_H


// .cpp file
#ifndef A_CPP
#define A_CPP
#include "A.h"

A::A() {
}

#endif // A_CPP






When I create the class like:


A a;



I get the error:

undefined reference to `A::A()'
You forgot to link the objects together:
This is a GCC error message. You should compile and link your program like
this:
g++ -c a.cpp -o a.o # "preprocess, compile, assemble a.cpp"
g++ -c main.cpp -o main.o # containing the main function
g++ main.o a.o -o app # whenever you modified a source file, run the
compiler with -c on that file and link all objects together.
On solution to the problem is to include A.cpp at the end of A.h like:
Please don't. Including it will cause problems later.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top