粉刺的一种简单形式

A simpler form of pimpl

本文关键字:一种 简单      更新时间:2023-10-16

为什么不选择这个设计:

// A.hpp
class A
{
public:
    void do_something();
};
// A.cpp
#include "A.hpp"
#include <vector>
std::vector<int> impl_database_for_do_something;
static void impl_helper_for_do_something(const std::vector<int>& database){}
void A::do_something(){ impl_helper_for_do_something(impl_database_for_do_something); }

代替这个:

// A.hpp
#include <vector>
class A
{
public:
    void do_something();
private:
    std::vector<int> database_for_do_something_;
    void helper_for_do_something(const std::vector<int>& database){}
};

我可以隐藏实现细节和加速编译与变量和静态函数定义在源文件?如果不是,这个设计有什么问题(除了继承)?

在第一种情况下,整个程序只有一个impl_database_for_do_something实例。你希望每个a的实例对应一个它的实例,所以代码在任何意义上都不是等价的。

如果你按照你的建议使用全局向量来存储状态,你将不得不以某种方式确保类A的不同实例使用向量的不同部分(除了这样做的明显困难之外,考虑到如果不同的线程使用A的不同实例,这会变得多么困难)。这种设计只有在A是单例时才有意义。

您的第一个设计有一个向量所有 A实例;后者每个实例有一个

这根本不是PIMPL:指向实现的指针。

你可以这样做:

// A.hpp
#include <boost/shared_ptr.hpp>
class A
{
public:
  A();
  void foo();
private:
  struct Impl;
  boost::shared_ptr<Impl> _impl;
};
// A.cpp
#include <vector>
#include "A.hpp"
struct A::Impl {
  std::vector<int> _data;
};
A::A(): _impl(new std::vector<int>()) {}
void A::foo() {
  _impl->_data.push_back(3);
}

警告:此代码没有处理正确的复制/赋值行为,留给读者作为练习。

相关文章: