1

While following the book C++ For Dummies, I have three files in my CodeBlocks project, main.cpp, Pen.h, and Pen.cpp. They look like this:

main.cpp:

#include <iostream>
#include "Pen.h"
//#include "Pen.cpp"

using namespace std;

int main()
{
    Pen MyPen = Pen();
    MyPen.test();
}

Pen.h:

#ifndef PEN_H_INCLUDED
#define PEN_H_INCLUDED

//#include "Pen.cpp" // Uncommenting this gives a different error

using namespace std;

class Pen
{
public:
    // attributes omitted

    // PROTOTYPES:
    // other functions omitted
    void test();
};

#endif // PEN_H_INCLUDED

Pen.cpp:

#include <iostream>
#include "Pen.h"

using namespace std;

//other function definitions omitted

void Pen::test()
{
    cout << "Test successful." << endl;
}

When I run the code as listed above, I get an "undefined reference to `Pen::test()'" error. To fix this, I changed the #include statements at the top of main.cpp to:

#include <iostream>
//#include "Pen.h"
#include "Pen.cpp"

This works as intended and correctly prints out "Test successful."

My question is this: what in the world is the point of putting a function prototype in a header file if I have to import the .cpp file later on anyways?

EDIT: It turns out this was a problem with not knowing how to use Code::Blocks rather than with the C++ language.

Sam L
  • 27
  • 4
  • 5
    Linking is a thing. – jxh Jan 12 '22 at 23:27
  • 7
    *"...if I have to import the .cpp file later on anyways"* - You don't. If you're `#include`-ing a cpp file, you're already architecturally broken. cpp files should be built with your toolchain as translation units, then the resulting object code linked into your final program/lib. – WhozCraig Jan 12 '22 at 23:27
  • The "unresolved reference" means that you forgot to give `Pen.o` (or `Pen.obj` depending on what toolchain you're using) to the linker to say "Oh, include this file in the program too." – Raymond Chen Jan 12 '22 at 23:29
  • 1
    `using namespace std` in a header file won't win you many friends. – Passerby Jan 12 '22 at 23:29
  • 1
    Good reading: [How does the compilation/linking process work?](https://stackoverflow.com/questions/6264249/how-does-the-compilation-linking-process-work) – user4581301 Jan 12 '22 at 23:34
  • How do I link things? How is it different from #include statements? – Sam L Jan 12 '22 at 23:40
  • Have you added the Pen.cpp file to your project? To add an existing file go to the Menu Project -> Add files... and select Pen.cpp – Sergio Jan 13 '22 at 08:48

2 Answers2

3

Assuming you're using gcc, you can compile and link in one step by supplying multiple .cpp files via the command line.

g++ Pen.cpp main.cpp

clang should be similar.

clang++ Pen.cpp main.cpp

An #include should never reference a .cpp file. At all. There's no good reason to do it. Include your headers and then supply the names of all .cpp files when you compile. If your project gets big and you have too many .cpp files to reasonably list, then it's time to break out a makefile or similar.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
1

In the main.cpp include the header file:
#include "Pen.h"

The Pen.h file it's ok.

You need to add the Pen.cpp file to the project tree.
Go to Project -> Add files... and add Pen.cpp

enter image description here

Sergio
  • 891
  • 9
  • 27
  • Yep, this fixed it. What's odd is that on the left pane Pen.cpp already looked like it was in the Sources file for the Pen project, but for some reason CB didn't act that way. – Sam L Jan 13 '22 at 17:44
  • After some trial-and-error I found out that simply adding the file to the project doesn't automatically tell CB to link it at compile time. In the file creation wizard you have to hit "All" under the "Add file to active project in build target(s):" option. – Sam L Jan 13 '22 at 17:52