Do I have to put THING_API
in front of the forward declared name thing_impl
?
It depends, but given the nature of the pimpl idiom, no you would not need to export it.
You could get warnings and errors about it not being exported, these can be silenced either for the entire project, or limit it to the scope of the member variable (as below);
class thing_impl;
class THING_API thing
{
public:
...
private:
#pragma warning(push)
#pragma warning(disable: 4251)
thing_impl* pimpl_;
#pragma warning(pop)
};
Other factors to consider in the implementation is to declare the "pimpl" implementation class thing_impl
as private inside the main thing
class to further limit potential access.
class THING_API thing
{
public:
thing(const thing&);
thing& operator=(const thing&);
thing(thing&&); // if needed
thing& operator=(thing&&); // if needed
~thing();
...
private:
class thing_impl;
#pragma warning(push)
#pragma warning(disable: 4251)
thing_impl* pimpl_;
#pragma warning(pop)
};
One thing to note is that when exporting a class from a DLL, the entire class will be exported, so make sure that the appropriate copy constructors, copy assignment operators and destructors are there (as above) and implemented (additional the move ones if required). If they are not there, the compiler will generate them and they are more than likely not going to be correct given the use of the pimpl_
member. To this end you could also consider using a std::shared_ptr
to assist in managing the pimpl_
.