使用私有 class 数据模式的成本是多少?

What's the cost of using private class data pattern?

我曾经将其作为库中的 TimeUnit 声明:

解决方案1:

typedef boost::posix::ptime TimeUnit;

TimeUnit createTimeUnit( int hours, int minutes );
std::string toString( const TimeUnit& timeUnit );

假设我想将其移动到更面向对象的东西:

解决方案2:

class TimeUnit : public boost::posix::ptime
{
public:
    TimeUnit( int hours, int minutes );

    std::string toString() const;
};

现在,假设我不希望使用这个 class 的库直接依赖于 boost,所以我想使用私有 class 数据模式来删除任何 boost来自我的头文件的引用:

解决方案3:

class TimeUnitPrivate;
class TimeUnit
{
public:
    TimeUnit( int hours, int minutes );
    ~TimeUnit();

    std::string toString() const;
public:
    TimeUnitPrivate* m_data;
};

TimeUnitPrivate 与 Solution2 的 TimeUnit 大致相同,新的 TimeUnit 只是:

TimeUnit::TimeUnit( int hours, int minutes ) : 
    m_data( hours, minutes )
{}

TimeUnit::~TimeUnit()
{
    delete m_data;
}

std::string TimeUnit::toString()
{
    return m_data->toString();
}

Solution3 非常聪明,我肯定会节省编译时间 + 限制 boost 依赖项。

但我想知道每个解决方案的成本是多少:

前两个解决方案在内存使用和性能方面完全相同。一个只是比另一个更 object-y,纯粹是偏好问题。

handle-body/pimpl 习语解决方案将占用更多内存(按指针的大小)并且速度较慢(每次调用的额外间接,创建时的额外分配)。慢多少?你得抓紧时间。与编译时间的加速和依赖性的减少相比,额外的内存使用和性能损失是否对您造成伤害?完全取决于您的项目正在做什么。对于某些应用程序,这种规模的性能丝毫不重要,因此加速编译当然值得。对于其他应用程序,这完全是不可能的。没有通用的答案。