Let's say I have a header file with a class that uses std::string
.
#include <string>
class Foo
{
std::string Bar;
public:
// ...
}
The user of this header file might not want std::string
to be included in his/her project. So, how do I limit the inclusion to just the header file?
You can't do that. If the user doesn't want to include
std::string
, then he or she should not use that class at all.std::string
will have to be included in the project in order to link your class correctly.I don't see how this can be done, or if it's possible in c++. The reason being: when the compiler sees the member of type "std::string", it must know what is the type in order to know its size. This information can only be obtained by looking into the class definition in a .h file.
One way the users can use a different string class in their source, is by using "using" construct:
Basically, you don't. Once you've included a file, all of the entities from that file are available for the remainder of the translation unit.
The idiomatic way to hide this sort of dependency is to rely on the pimpl idiom.
That said, why would code using
Foo
care that<string>
was included? All of its entities are in thestd
namespace (well, except that<string>
might include some of the C Standard Library headers, but generally you should code with the expectation that the C Standard Library headers might be included by any of the C++ Standard Library headers).The user of your class must include
<string>
, otherwise their compiler will not know how big aFoo
object is (and ifFoo
's constructors/destructors are defined inline, then the compiler also won't know what constructor/destructor to call for thestring
member).This is indeed an irritating side-effect of the C++ compilation model (basically inherited intact from C). If you want to avoid this sort of thing entirely, you probably want to take a look at the PIMPL idiom.