1

我有一个包含 boost::shared_array 成员的类。其他成员不是动态的——只是一堆整数,没有指针。我希望这样一个类的默认复制构造函数会很好。

这是我的假设:

  1. 假设我有这个类的一个实例,orig

  2. orig的 shared_array 成员的引用计数为 1。

  3. 现在我创建一个 orig 的副本:

    复制=原件;

  4. 我现在希望copyorig都有指向相同底层内存的 shared_arrays,每个引用计数为 2。

以上是正确的吗?

当有 boost::shared_* 成员时,我被各种警告默认复制构造函数的人吓坏了——但我永远找不到解释为什么默认值会/可能是坏的。例如,这里有人说应该定义明确的副本/分配,但没有解释原因:

https://stackoverflow.com/a/716112/629530

有人可以澄清何时需要为包含 boost::shared_* (shared_array 和 shared_ptr) 成员的类定义复制构造函数和赋值运算符吗?

4

1 回答 1

1

以下类将 Pimpl Idiom 与 shared_ptr 结合使用:

class location
{
    struct impl
    {
        double _latitude;
        double _longitude;
    };
    std::shared_ptr<impl> _impl;
public:
    location(double latitude, double longitude)
        : _impl{new impl{latitude, longitude}}
    { }
    void move_to(double latitude, double longitude)
    {
        _impl->_latitude = latitude;
        _impl->_longitude = longitude;
    }
    // ...
};

代码编译并工作。但是,有一个奇怪的行为:

location london{51.51, 0.12};
location paris = london;
paris.move_to(48.86, 2.35);
std::cout << "London: " << london << '\n'; // prints 48.86/2.35

更改对象的副本也会影响原始对象。在这种情况下,最好使用std::unique_ptr而不是std::shared_ptr,因为我们将被迫编写自己的复制构造函数。

在某些情况下,需要 的行为std::shared_ptr。让我们添加一个成员变量metric,用于计算两个位置之间的距离(因为计算距离可能有不同的策略):

    std::shared_ptr<metric> _metric;
    double operator-(const location& rhs) const
    {
        return _metric->distance(*_impl, *rhs->_impl);
    }

在这种情况下,astd::shared_ptr可以完美运行,因为度量不是位置感知状态的一部分,并且无法更改度量。

于 2013-04-11T17:59:47.850 回答