pete
pete

Reputation: 2046

Multiple Source .cpp Files Problems

I've separated my large program into a number of .cpp files, e.g. display.cpp, gui.cpp, display.h, gui.h, etc...

These files are separated just for readability, not necessarily indicative of any sort of dependency scheme.

Initially I had a lot of trouble getting them to compile, because functions from display will call functions from gui, AND vice versa. Whichever one I include first, it will still depend on the other's functions. But I finally figured out that I need to first include all the .h files, then include all the .cpp files, in my main program.

Example, in the main_program.cpp:

#include "display.h"
#include "gui.h"
#include "display.cpp"
#include "gui.cpp"

Unfortunately I also realized that in order to compile I had to remove all the other .cpp files from what is considered "source" code in the Visual Studio debugger. That way it just compiles main_program.cpp, including the other files as needed. If I include display.cpp and gui.cpp in the "source" sidebar it will error.

This is probably the wrong way of doing things and I feel like I am doing something wrong. I would like to be able to put all the source files in the sidebar and still have it compile. Of course the above was just an example and I have not two, but more like 10 different .cpp files that all call each others' functions. Please advise on how to better design this.

Upvotes: 0

Views: 4537

Answers (4)

Dietmar Kühl
Dietmar Kühl

Reputation: 154045

You generally never want to include .cpp files! Also, you should get used to factoring your code according to dependency hierarchies which shall not include any cycle! For small proframs this is just helpful, for large software it is essential.

Upvotes: 2

Mooing Duck
Mooing Duck

Reputation: 66981

That is... not the right way to approach things. If I had to speculate, I'd guess you aren't using function declarations that aren't definitions. A function definition is what you probably have:

void dothing(int param) { //function definition
    throw param;  
}

What goes in the header is the function declaration, which would be like this:

void dothing(int param); //function declaration

This merely lets other cpp files know that the file exists for calling, but they don't need to know the details. Generally, functions will go in your .cpp files as you (seem to have) done. Each function will have a declaration in a header file:

display.h

#include "velocity.h" //we need the details, so we include

void dothing(int param); //function declaration

class  coordinate; // this is a class declaration
                   //this header needs to know about coordinates
                   //but doesn't need the details
                   //otherwise we'd have to include "coordinate.h"

struct object { //class definitions usually go in headers
    coordinate* member; //pointers don't need to know the details
    velocity speed; //actual object needs the details
    float function(float param); //function declaration
};

display.cpp

void dothing(int param) { //function definition
    throw param;  
}

float object::function(float param) { //member function definition
}

Then, if a cpp file neads access to a function in another cpp file, it includes the appropriate header:

main.cpp

#include "display.h"

int main() {
    object a;
    a.function(3.4); //can call the member just fine
    dothing(4); //it can call the function just fine.
}

Remember that headers should prefer declaring a class (in my example: coordinate to including more headers wherever possible. Also remember that templates have completely different rules altogether.

Upvotes: 1

Cody Gray
Cody Gray

Reputation: 244991

The problem is that you've included .cpp files, that's why you had to tell Visual Studio to pretend that these files were not "source" code, because it always compiles source code files. So the simple solution is don't do that.

Including just the header files (.h) in each .cpp file as required should be sufficient. So, for example, if gui.cpp needs to call functions defined in display.cpp, then you should #include the display.h header file at the top of the gui.cpp code file.

Use forward declarations to eliminate any lingering circular dependencies.

Upvotes: 1

Lander
Lander

Reputation: 3437

I had a similar problem before in which I had two header files referencing each other, calling functions, etc. To fix it, I first made sure that all of my header guards were in check (#ifndef HEADER_DEFINE, #pragma once, etc.), then in the class files I would include the header that was being problematic.

e.g. if I have Pie.h and Cherries.h, and Pie.h included Cherries.h and vice versa, then in the Pie.cpp file, I had the include for Cherries.h (and vice versa).

Upvotes: 0

Related Questions