4

I have a large C++ file (SS.cpp) which I decided to split in smaller files so that I can navigate it without the need of aspirins. So I created

SS_main.cpp
SS_screen.cpp
SS_disk.cpp
SS_web.cpp
SS_functions.cpp

and cut-pasted all the functions from the initial SS.cpp file to them.

And finally I included them in the original file :

#include "SS_main.cpp"
#include "SS_screen.cpp" 
#include "SS_disk.cpp" 
#include "SS_web.cpp"
#include "SS_functions.cpp"

This situation remains for some months now , and these are the problems I've had :

  • The Entire Solution search (Shift-Ctrl-F in VS) does not search in the included files, because they are not listed as source files.

  • I had to manually indicate them for Subversion inclusion.

Do you believe that including source files in other sources is an accepted workaround when files go really big ? I should say that splitting the implemented class in smaller classes is not an option here.

Amro
  • 123,847
  • 25
  • 243
  • 454
Wartin
  • 1,965
  • 5
  • 25
  • 40
  • Splitting it into separate classes is not an option in whose opinion? I suggest that you have a serious design issue if that is the case. In what world would domains such as "web" and "screen" for example, be part of the same single object? The very fact that you chose to split them up in that manner indicates that they are candidates for separate classes. And as for "functions"... well I suggest that you have many more candidates for classes than just four. – Clifford Oct 31 '09 at 22:16
  • The class SS is similar to other classes. The other classes are much simpler, for example they have only some "Read" functions (ReadFromWeb(), ReadFromKeyboard(), ReadFromDisk() etc). In my case it is not meaningful to split the SS class in smaller classes just because the source file is large. – Wartin Nov 01 '09 at 00:36
  • I'm curious. How big is this source file that is too big to be just one source file? – kidnamedlox Nov 01 '09 at 08:33
  • It was 102 KB. Not huge but slows down navigation considerably. – Wartin Nov 01 '09 at 14:00

6 Answers6

9

There are times when it's okay to include an implementation file, but this doesn't sound like one of them. Usually this is only useful when dealing with certain auto-generated files, such as the output of the MIDL compiler. As a workaround for large files, no.

You should just add all of those source files to your project instead of #including them. There's nothing wrong with splitting a large class into multiple implementation files, but just add them to your project, including them like that doesn't make much sense.

-- Also, as an FYI, you can add files to your projects, and then instruct the compiler to ignore them. This way they're still searchable. To do this, add the file to the project, then right-click it, and go to Properties, and under "General" set "Exclude from Build" to Yes.

Gerald
  • 23,011
  • 10
  • 73
  • 102
8

Don't include cpp files in other files. You don't have to define every class function in one file, you can spread them across multiple files. Just add them individually to the project and have it compile all of them separately.

kidnamedlox
  • 806
  • 1
  • 7
  • 14
  • Hmm but will it then be possible to compile only the classe's files without having to point to each one separately ? – Wartin Oct 31 '09 at 06:42
  • 2
    Assuming you're using Visual Studio, you can shift-click the implementation files to select them all in order to compile them. Creating a "Filter" to put all of the implementation files for that class in can help keep it organized as well. – Gerald Oct 31 '09 at 06:48
  • Hmm, but compilers tend to do a better job of optimisation when they compile more code at once. – alex tingle Oct 31 '09 at 12:05
  • @Wartin, Gerald's got it. @Alex, the problem is if you change any of those implementation files, you have to compile all of them. Since this class is pretty big as it is, I assume that would be a lengthy compile time. Also, I know don't if you are entirely correct. The idea that having more files causes worse optimizations seems like it would be a major issue in large projects and libraries. – kidnamedlox Oct 31 '09 at 15:17
  • @alex tingle, Visual C++ can optimize an entire project as a single source file. – Drew Dormann Oct 31 '09 at 22:52
4

You don't include implementation (.cpp) files. Create header files for these implementation files containing the function/class declarations and include these as required.

dirkgently
  • 108,024
  • 16
  • 131
  • 187
3

There are actually times you will want to include CPP files. There are several questions here about Unity Builds which discuss this very topic.

Community
  • 1
  • 1
Adisak
  • 6,708
  • 38
  • 46
2

You need to learn about Separate compilation, linking, and what header files are for.

You need to create a header file for each of those modules (except possibly main.cpp). The header file will contain the declarative parts of each .cpp source file, and the .cpp files themselves will contain the instantive parts. Each unit can then be separately compiled and linked. For example:

main.cpp

#include "function.h"

int main()
{
    func1() ;
}

function.h

#if !defined FUNCTION_H
#define FUNCTION_H

extern void func1() ;

#endif

function.cpp

void func1()
{
    // do stuff
}

Then function.cpp and main.cpp are separately compiled (by adding them to the sources for the project), and then linked. The header file is necessary so that the compiler is made aware of the interface to func1() without seeing the complete definition. The header should be added to the project headers, then you will find that the source browser and auto-completion etc. work correctly.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • He's breaking up a single class into multiple implementation files, so he really only needs the one header file with the class definition to be included in each of the files. – Gerald Oct 31 '09 at 09:31
  • @Gerald: Maybe so, but a single class dealing with "screen", "disk", "web" and (of all things) "functions"!? I suggest that there is a design issue here too. – Clifford Oct 31 '09 at 22:10
2

What bothers me with this question is the context of it. A large cpp file has been created, large enough to warrant thinking about splitting it into smaller more manageable files. The proposed split is:
SS_main.cpp
SS_screen.cpp
SS_disk.cpp
SS_web.cpp
SS_functions.cpp

This seems to indicate that there are separate units of functionality from a specification and design perspective. We can only guess at the coupling between these units of code.

However, it would be a start to define these code units such that each new cpp file has its own header file thus defining the interfaces of these units and the (low) coupling between them to achieve (high) cohesion for each unit.

We are refactoring here.

It is not acceptable to use included cpp files in this context it as does not provide any advantages. The only time I've come across included cpp files is when a one is included to provide code for debug code, and example being to compile non-inline versions of functions. It helps in stepping through code in the debugger.

Sam
  • 694
  • 4
  • 6
  • Exactly my thoughts when I saw this question. One class, one responsability. – KeatsPeeks Oct 31 '09 at 10:29
  • We are only told it is a class in the last sentence of the question and that splitting it into smaller classes is not an option. We must also assume that the class definition is in the cpp file as well. So how does client code use this class? Include the cpp file? Altogether it smells rather badly. – Sam Oct 31 '09 at 11:52