C++ project layout - c++

I am completely confused as to the proper way to layout a C++ project.
I had all my classes in separate .cpp files, with their definitions in .h files. I then had one "header.h" which contained all the class headers, external dependencies and a few other things. But I wasn't able to use class names in the header files, where I needed to declare a pointer to one.
Can someone please explain the proper object-orientated layout for a C++ project.

You can fix the problem "wasn't able to use class names in the header files, where I needed to declare a pointer to one" by using forward class declarations, like:
class myClass;
However, having every class include a header.h that then includes every class is overkill. Instead, you should have each class specifically include only the classes and external dependencies that it actually needs.

Related

Is it good C++ to define classes in .cpp file?

I am a beginner in C++. I have a question regarding C++ design.
My file contains A,B,C,D,E class definitions. Class A contains the API which is used by other applications. I have defined this in a .h file. Classes B,C,D & E define concrete classes by inheriting an abstract class which is provided by some library. These definitions are not used by any external application, but only used by class A.
I have seen online that all the class definitions are provided in an .h file and the function implementations in a .cpp file. My question here is, even though class B,C,D & E definitions are not used externally by anyone, should I define them in the .h file? If I do define them there anyway, I cannot expose them to other applications, right?
If a class is only used locally in one module, you can declare it in the .cpp file. This is actually good practice; don't expose more than necessary.
In a case where you need to define a class (or function, etc.) in a header (for example, to share it between several related .cpp file) but you do not want to expose it publicly, you can have a separate, private header file which is only included in the relevant places, but is not made public. This can be hinted at by appending "private" to the header file name.

How to import a class that is not inside header file

I am relatively new to c++. So apologies if this q is naive. But I couldn't get an answer so asking it here.
I have an existing .cpp file (one.cpp) which has a class (class A) defined inside it(one.cpp does not have corresponding one.h). Now I want another class (class B) in another file (two.h) to extend class A. But as A is not inside a header, I cannot do #include one.h
I am thinking of creating one.h, but class A is huge, so trying to avoid it.
Is there an easier way to do it?
In order for the linker to be able to identify class A in two.h, it would need reference to that class through a header file. As far as I know, there's no way around that.
Keep in mind that you only need to put the function prototypes in the header, not the actual definition.
You can include one.cpp in your two.h file like this #include "one.cpp". However this is considered bad practice. What you should do is create a header file for your class A.
Keep in mind that you don't have to actually implement the class in the header file.

How to avoid include files spreading due to template classes

Due to the implementation of a template class in a header file, I have to include the other includes used in the implementation of the class in the header file.
Because of that, each time I include my template class that bring all other the inclusions and so on.
This could bring to an eccessive spread of inclusion, or even unnecessary for the context.
So what's the best way to deal with this issue?
Edit: Since I've not explictely mentioned it, I'm not talking about cases where forward declaration could solve it like in a normal .h/.cpp separation, but when you have to include the header, and since you don't have the cpp, you are force to use it in .h
Edit 2: Let's say my template class has a function with a dependency with a third class library. Each class using my template class now has the same depency, or can access to that header which both I could not want to. Does it exists a way to avoid that?
Use forward declaration where ever appropriate instead of #include.
Header file should #include only the needed and rest should go in source file.

(C++) where do I put all my templates?

I have different classes all arranged in a hierarchy.
To reduce the amount of code, I started creating template functions. The base class will use the template functions and some of the derived classes will also use the same functions. Where am I suppose to put all of these templates so I don't get undefined reference issues like I have been? Should I put all the definitions in a header file and then just include that header files in the .cpp part of the class that call the functions. will that work? As of right now, all of my classes(class.cpp, class.h) compile fine, but everything blows up during the linking. I tried to put all the templates in a namespace and then include that namespace in the implementation of all my classes but that doesn't seem to work. My question is, how would you go about making a separate entity that just holds templated functions that any class can use on it's data members?
The definitions of template functions and template classes belong in header files, not .cpp files.
This is because the compiler essentially has to generate a brand new function for each set of template parameters that's used in the file that #includes the header. If the template function were defined in a .cpp file, then all of the appropriate versions of these functions would have to be generated without knowing what the calling code looks like, and that's basically impossible. (You do get duplicate definitions of template functions this way, but the linker removes those and makes sure there's only one copy if each template instantiation in the final binary.)
I see a lot of people confused by this thing... templates are not types.
They become types when instantiated.
For this reason members of templates must stay in the same data unit you are going to use them.
If you template is generic and you want to use it in all your code, just put everything in header files.
Now, if you don't like (and i would understand that) that you show declarations and definitions and implementation all in the same file, you can split templates in two different files.
For example, "list.h" with your declaration and "list.inc" with your implementation.
To make it work, you have to include both.

Two classes that refer to each other

I'm new to C++, so this question may be basic:
I have two classes that need to refer to each other. Each is in its own header file, and #include's the other's header file. When I try to compile I get the error "ISO C++ forbids declaration of ‘Foo’ with no type" for one of the classes. If I switch things so the opposite header gets parsed first I get the same error with the other class.
Is it possible in C++ to have two classes that need references to each other?
For more detail: I have an "App" class and a "Window" class. App needs to refer to Window to make the window. Window has a button that calls back to App, so it needs a reference to App. If I can't have two classes refer to each other, is there a better way to implement this?
You can use forward declarations in the header files to get around the circular dependencies as long as you don't have implementation dependencies in the headers. In Window.h, add this line:
class App;
In App.h, add this line:
class Window;
Add these lines before the class definitions.
Then in the source files, you include the headers for the actual class definitions.
If your class definitions reference members of the other class (for example, in inlines), then they need to be moved to the source file (no longer inline).
Forward declaration is the way to go.
If you are using pointers\reference in class header then Forward declaration at both sides would work for you.
If you are creating the object as a class member then you must include header itself. ( Forward declaration won't work as compiler needs class definition for knowing the size).
Refer C++ FAQ for solving such senario:
If you are creating the Window as member then include the Window header in App but at the same time Window shouldn't include the App's header. Use the combination of pointer to App and the forward declaration there.