Reputation: 33
Suppose I have the following class:
Foo.h:
class MyVectorClass;
class Foo {
public:
MyVectorClass get();
...
}
Following the commonly agreed pattern to forward declare everything that can be forward declared, and since MyVectorClass
is used only as a return type of a method, MyVectorClass
is forward declared. Then, any user of this class should include MyVectorClass.h
to be able to use the method get
.
Bar.cpp:
#include "Foo.h"
#include "MyVectorClass.h"
Foo foo;
...
MyVectorClass result = foo.get();
The fact that in order to use class Foo
we need to include some additional headers makes me question the idea of a forward declaration here. This is even more confusing for me if I use auto instead of MyVectorClass
, which is preferable since I don't really care about MyVectorClass
much, anything with a vector-like interface is good enough for me.
#include "Foo.h"
#include "MyVectorClass.h"
Foo foo;
...
auto result = foo.get();
When reading this code, it's very hard to find out why do we include MyVectorClass.h
. And when the interface of Foo
changes, and get
starts to return AnotherVectorClass
, or std::vector
, we should remove the old MyVectorClass.h
in every user of the get method and include an appropriate new header instead.
Is forward declaration really worth it here?
Upvotes: 3
Views: 1546
Reputation: 153
Again, auto
is statically typed and won't help you get the desired dynamic polymorphism. If you need it, you should use iterators or pointers.
So one solution here will be to inherit all of your SomeVector
implementation classes from the same base class so you wouldn't need to worry about editing the includings every time you change something.
Alternatively, you can work with the data that get()
gives you first hand, provided MyVectorClass
has proper iterators, and never use the intermediate SomeVector
type at all. This is better for your case, as you can also use the stl vector itself.
Upvotes: -1
Reputation: 8141
I think the problem is saying that anything that can be forward-declared should be. Forward declarations gives benefits in terms of compilation speed, but at the expense of convenience.
One example is the one you gave. Another is that even IDEs and tools (such as VisualAssist) sometimes don't know what to make of a forward-declaration, and are not able to jump to the actual type. The same goes for refactoring tools.
So the question of is it worth it or not depends on whether or not the compilation speed improvement would be worth it.
If you want to give a slightly better hint to users of the class, there's another option: you can include all of its dependencies in a "Foo.inl" file, which users would need to include in order to use it safely, without too much hassle, and in a more future-proof way.
Upvotes: 1