我正在维护一个可能需要相当长的时间来构建的项目,因此我正在尝试尽可能减少依赖项。如果 pImpl
习语可以使用某些类,并且我想确保正确执行此操作,并且这些类可以与 STL(尤其是容器)很好地配合。下面是我的示例计划做什么 - 这看起来不错吗?我使用 std::auto_ptr
作为实现指针 - 这可以接受吗?使用 boost::shared_ptr
会是一个更好的主意吗?
以下是 SampleImpl
类的一些代码,该类使用名为 Foo
和 Bar
的类:
// SampleImpl.h
#ifndef SAMPLEIMPL_H
#define SAMPLEIMPL_H
#include <memory>
// Forward references
class Foo;
class Bar;
class SampleImpl
{
public:
// Default constructor
SampleImpl();
// Full constructor
SampleImpl(const Foo& foo, const Bar& bar);
// Copy constructor
SampleImpl(const SampleImpl& SampleImpl);
// Required for std::auto_ptr?
~SampleImpl();
// Assignment operator
SampleImpl& operator=(const SampleImpl& rhs);
// Equality operator
bool operator==(const SampleImpl& rhs) const;
// Inequality operator
bool operator!=(const SampleImpl& rhs) const;
// Accessors
Foo foo() const;
Bar bar() const;
private:
// Implementation forward reference
struct Impl;
// Implementation ptr
std::auto_ptr<Impl> impl_;
};
#endif // SAMPLEIMPL_H
// SampleImpl.cpp
#include "SampleImpl.h"
#include "Foo.h"
#include "Bar.h"
// Implementation definition
struct SampleImpl::Impl
{
Foo foo_;
Bar bar_;
// Default constructor
Impl()
{
}
// Full constructor
Impl(const Foo& foo, const Bar& bar) :
foo_(foo),
bar_(bar)
{
}
};
SampleImpl::SampleImpl() :
impl_(new Impl)
{
}
SampleImpl::SampleImpl(const Foo& foo, const Bar& bar) :
impl_(new Impl(foo, bar))
{
}
SampleImpl::SampleImpl(const SampleImpl& sample) :
impl_(new Impl(*sample.impl_))
{
}
SampleImpl& SampleImpl::operator=(const SampleImpl& rhs)
{
if (this != &rhs)
{
*impl_ = *rhs.impl_;
}
return *this;
}
bool SampleImpl::operator==(const SampleImpl& rhs) const
{
return impl_->foo_ == rhs.impl_->foo_ &&
impl_->bar_ == rhs.impl_->bar_;
}
bool SampleImpl::operator!=(const SampleImpl& rhs) const
{
return !(*this == rhs);
}
SampleImpl::~SampleImpl()
{
}
Foo SampleImpl::foo() const
{
return impl_->foo_;
}
Bar SampleImpl::bar() const
{
return impl_->bar_;
}
最佳答案
如果 Foo 或 Bar 在复制时可能会抛出异常,则应考虑使用 copy-and-swap 进行赋值。如果没有看到这些类的定义,就不可能说它们是否可以。如果没有看到他们发布的界面,就不可能说他们将来是否会在你没有意识到的情况下改变这样做。
正如 jalf 所说,使用 auto_ptr 有点危险。它在复制或分配时的行为不符合您的要求。快速浏览一下,我认为您的代码不允许复制或分配 impl_ 成员,因此可能没问题。
如果您可以使用scoped_ptr,那么编译器将为您完成这项棘手的工作,检查它是否被错误地修改。 const
可能很诱人,但你无法交换。
关于c++ - STL 友好的 pImpl 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2028107/