如果您的对象B需要对象A的私有成员的副本,并且私有成员被Pimpl隐藏,那么如何在不暴露内部的情况下实现它? // 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.
答案 0 :(得分:7)
// 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;
}
答案 1 :(得分:3)
Foo
需要实现构造函数,复制构造函数,析构函数和赋值运算符,执行“正确的事情” - 允许您执行以下操作: '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;
}
现在你可以安全地做到:
Foo A;
Foo B;
A = B;
答案 2 :(得分:0)
除了(复制构造函数,ec。)之外的其他问题,如果您想要访问impl::data
而不向所有客户端强加<string>
标题,您可以执行以下操作:
// 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;
这是一个具有std::string Foo::data() const
成员函数的黑客攻击方法。我们的想法是,只有需要它的客户才能包含<string>
标题。
免责声明:我真的不喜欢这种做法。它非常不优雅,不太可能真正增加编译时间。一些编译器缓存(或预编译)标准库头文件,以帮助人们避免这种混乱。