How do you exchange private data with Pimpl without exposing your internals?
If you have an object B that needs a copy of a private member of 开发者_运维技巧an object A, and the private member is hidden by a Pimpl, how do you make it happen without exposing your internals? // Foo.h
class Foo
{
private :
struct impl ;
impl * pimpl ;
};
// Foo.cpp
struct impl { std::string data; }
//main.cpp
Foo A;
Foo B;
// I want A::pimpl->data copied to B::pimpl->data and I don't want std::string exposed in my Foo header.
// header
class Foo
{
public:
void Copy( const Foo & );
private :
struct impl ;
impl * pimpl ;
};
//cpp file
struct impl {std::string data; }
void Foo::Copy( const Foo & f ) {
pimpl->data = f.pimpl->data;
}
Foo
needs to implement a constructor, a copy constructor, a destructor and an assignment operator, doing the "right thing" - allowing you to do e.g. 'A = B;'
// Foo.h
struct FooImpl;
class Foo
{
Foo(Foo const &);
Foo();
~Foo();
Foo & operator=(Foo const & RHS);
private:
FooImpl * pimpl;
};
// Foo.cpp
struct FooImpl {std::string data; }
Foo & Foo::operator=(Foo const & RHS) {
*pimpl = *RHS.pimpl;
return *this;
}
Foo::Foo(Foo const & V) {
pimpl = new FooImpl(*V.pimpl);
}
Foo::Foo() {
pimpl = new FooImpl;
}
Foo::~Foo() {
delete pimpl;
}
Now you can safely do:
Foo A;
Foo B;
A = B;
Other issues aside (copy constructor, ec.), if you want to access impl::data
without imposing the <string>
header to all your clients, you can do something like the following:
// Foo.h
class FooUtil;
class Foo
{
friend class FooUtil;
private :
struct impl ;
impl * pimpl ;
};
// FooUtil.h
#include <string>
class FooUtil
{
public:
static std::string data_of(const Foo&);
};
// Foo.cpp
struct impl { std::string data; }
std::string FooUtil::data_of(const Foo& foo)
{
return foo.impl->data;
}
//main.cpp
Foo A;
Foo B;
This is a hack-ish work-around for having a std::string Foo::data() const
member function. The idea is that you can have the <string>
header included by only the clients who need it.
Disclaimer: I really don't like this approach. It's very inelegant and is unlikely to really increase compile times. Some compilers cache (or pre-compile) standard library headers so as to help people avoid this kind of mess.
精彩评论