Reputation: 805
I want to export a class from a DLL. It uses the Pimpl idiom like:
#ifdef THING_EXPORT
#define THING_API __declspec(dllexport)
#else
#define THING_API __declspec(dllimport)
#endif
class thing_impl;
class THING_API thing
{
public:
...
private:
thing_impl* pimpl_;
};
The constructor or destructor (or any method) of thing_impl
will not be available outside of that DLL. Do I have to put THING_API
in front of the forward declared name thing_impl
?
Upvotes: 1
Views: 1168
Reputation: 30606
Do I have to put
THING_API
in front of the forward declared namething_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_
.
Upvotes: 1