0

I have many models in my project, and some other classes just need the class declaration and pointer type aliasing. It does not need to know the class definition, so I don't want to include the model header file. I extract all the model's declaration into one file to let every classes reference one file.

model_forward.h

class Cat;
typedef std::shared_ptr<Cat> CatPointerType;
typedef std::shared_ptr<const Cat> CatConstPointerType;

class Dog;
typedef std::shared_ptr<Dog> DogPointerType;
typedef std::shared_ptr<const Dog> DogConstPointerType;


class Fish;
typedef std::shared_ptr<Fish> FishPointerType;
typedef std::shared_ptr<const Fish> FishConstPointerType;

enum CatType{RED_CAT, YELLOW_CAT, GREEN_CAT, PURPLE_CAT}

enum DogType{HATE_CAT_DOG, HUSKY, GOLDEN_RETRIEVER}

enum FishType{SHARK, OCTOPUS, SALMON}

Is it acceptable practice? Should I make every unit, which needs a class declaration, depends on one file? Does it cause high coupling?

Or I should put these pointer type aliasing and enum definition inside the class back?

cat.h

class Cat
{
    typedef std::shared_ptr<Cat> PointerType;
    typedef std::shared_ptr<const Cat> ConstPointerType;

    enum Type{RED_CAT, YELLOW_CAT, GREEN_CAT, PURPLE_CAT}
    ...
};

dog.h

class Dog
{
    typedef std::shared_ptr<Dog> PointerType;
    typedef std::shared_ptr<const Dog> ConstPointerType;

    enum Type{HATE_CAT_DOG, HUSKY, GOLDEN_RETRIEVER}
    ...
}

fish.h

class Fish
{ ... };

Any suggestion will be helpful.

0

2 Answers 2

1

Having a single file with all your class declarations seems like asking for trouble to me. There are architectural as well as tooling based reasons for my statement.

Let's look at tooling first. Most compilers can generate partially compiled files (such as .pch) based on which header files are included. These files are recreated only when those header files change. For large enterprise projects, this can mean the difference between a 5 min build and a 1 hour build. If you put all your declarations in one file, adding a single class will trigger a full build - not too desirable. There are intense debates around whether to use pre-compiled files in the first place, but this point is definitely something to keep in mind.

Many tools such as IDEs also use header scope to determine the level of auto-complete, etc. With a global header file, I've seen IDEs slow to a crawl as they try to process the massive include tree.

Secondly, as your project grows and you start using hundreds of classes, having them all declared in a single file will cause a lot of unnecessary coupling. The whole point of header files is to specify the compilation/lookup scope for your objects. It is better for each class to know only what it strictly needs. This enables future modularization and extensibility.

0

My instant response is: don't do that! When you mix declarations of classes together in the same file you introduce dependencies and coupling that will come back to bit you.

But beneath that I detect another problem. You have CPP files and H files, and the H files contain details of the private implementation (what you call the model header, I think). You quite rightly don't want to expose details of the implementation to every caller, and this is the solution you are considering.

This is a well known problem in C++, and there are solutions to it (although they all have their own problems). Probably the best known in PIMPL (for private implementation).

So my advice is to focus on tackling the problem of concealing the implementation from casual users of your classes, perhaps using PIMPL, and resist the temptation to create one header to rule them all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.