1

Currently, I am writing a few classes, all of which inherit from a base class and somehow enrich it. All of these classes use templates in order to take different elements as parameters (the classes are all variations of an abstract vector class). So I wrote all of the code in one big .hpp file because I read that splitting the code in .hpp and .cpp would cause linker problems (Splitting templated C++ classes into .hpp/.cpp files--is it possible?) and it wouldn't work.

So I was wondering, since it's not really clean and clear to have everything in a big .hpp file, should I split it and how would I do the splitting the right way in order to keep the code as intact as possible? Should I import the child classes into the base class? Do I have to forward declare all my classes in every .hpp file or not? How would the splitting interact with the templates.

If the code is necessary, I can add it. Just trying to keep it short if it isn't.

Community
  • 1
  • 1
  • How about one header file per class, instead of just a single large header file? And you could even split out the inline functions into separate header files included by the class header file. – Some programmer dude Dec 10 '15 at 12:28
  • I see. Yes that was my initial idea, though I haven't inlined any functions since I haven't looked much into that. In that case, would I have to do anything in particular in order to make this work for templates or is it the same as when splitting regular inherited classes? – DefinitelyNotMe Dec 10 '15 at 12:31

3 Answers3

3

Files:

header.hpp
something1.ipp
something2.ipp
something3.ipp

Content of header.hpp:

#ifndef COMPANY_PROJECT_HEADER_HPP
#define COMPANY_PROJECT_HEADER_HPP 1

#include "something1.ipp"
#include "something2.ipp"
#include "something3.ipp"

#endif

Easy peasy. #include is just a "copy-and-paste" operation so you can do what you like to arrange your files in a pleasing, and easy-to-maintain organisational structure.

All the files are headers, but I've given the "sub-headers" the extension .ipp to distinguish them.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 1
    I see. It seems to work the same way as splitting regular code. I thought it would differ if I was using templates! Thank you I will try it asap. – DefinitelyNotMe Dec 10 '15 at 12:32
  • 1
    @DefinitelyNotMe Not exactly the same way, there is an important difference. Normally you `#include` the `.h` file in the `.cpp` file, note that with templates it is basically the other way around. This is due to the reasons described in the link you posted in your original question. – Cory Kramer Dec 10 '15 at 12:35
  • Yes, that's true. It's the other way around here :) – DefinitelyNotMe Dec 10 '15 at 12:37
3

As far as splitting the code up, there is a technique for templated code where you can split up the declarations and definitions, at least visually (you'll see why I make that distinction in a moment). So you first start with the header, that will contain just your class and function declarations

Foo.h

template <typename T>
T some_foo(T x);        // declaration

#include "Foo.inl"

Then you make a separate file for the implementation. Note that we #include this .inl file in our header, so as far as the compiler is concerned all of the code still exists in the header. Doing it this way is just for human readers, but this way you can split up the actual implementation code into separate files and just include them at the end of the header.

Foo.inl

<template <typename T>
T some_foo(T x)            // definition
{
    return x + 5;
}
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 1
    Oh that way the Foo.inl would be something like the .cpp file we usually use to write the implementation, except that we #include it the other way around. I see, this seems reasonable. – DefinitelyNotMe Dec 10 '15 at 12:36
1

So I wrote all of the code in one big .hpp file because I read that splitting the code in .hpp and .cpp would cause linker problems ... and it wouldn't work.

That only implies that you must not split the definition of the function templates from their declaration (or the definition of member function of a class template from the definition of the template). There is no reason to put the definition of all templates into a single header - which your post seems to imply that you did.

So I was wondering, since it's not really clean and clear to have everything in a big .hpp file, should I split it

Sure.

and how would I do the splitting the right way

Just be sure to keep the definitions of the templates in the same file that declared them - as described in the answers to the linked question. If you think that's messy, then you can put the definitions into another header and include that in the declaring header.

Do I have to forward declare all my classes in every .hpp file or not?

Only in headers that refer to the declarations, but don't need the complete definition.

eerorika
  • 232,697
  • 12
  • 197
  • 326