我有一些(在我看来)相当具体的所有权要求:我有一个基本上解释双精度数组的类是一种特定的方式(一些相当大的矩阵的串联),并且想与一个 C 库进行通信,然后在另一种方式(一个很长的数学向量)。在某些情况下,我想解释由 C 库传递给回调的指针,即不获取所有权。在这种情况下,复制将是非常不切实际的。在其他情况下,我想自己分配缓冲区,然后自己将其传递给 C 库。在这种情况下,我的代码拥有缓冲区。
我创建了一个“构建块”,将双数组解释为矩阵(使用boost::numeric::ublas::shallow_array_adaptor
,但这几乎无关紧要),如下所示:
class Foo {
public:
explicit Foo(double *buffer);
Foo(const Foo &) = delete;
Foo(Foo &&) = delete;
Foo &operator=(const Foo &) = delete;
/* Some accessors. */
protected:
Foo &operator=(Foo &&) = default;
private:
/* Some things that store pointers into the buffer. */
};
复制和移动是被禁止的,这样实例就不会被意外地创建或移动到超出缓冲区本身寿命的地方。当然,可以通过直接将指针传递到某处来故意创建此类实例,但可以更容易地在源代码中发现。
我的问题的第一部分:让“通过缓冲区所有权增强”成为 的子类是否有意义?Foo
Foo
拥有- 的每一个操作Foo
都是可能的Foo
,另外,拥有-Foo
可以自由复制和移动。闻起来像是满足了 Liskov 替换原则。能够以相同的语法方式处理拥有Foo
,Foo
而无需在拥有中编写一堆方法,Foo
将委托给成员变量是非常舒服的。
另一方面,可能有 owner-of- Foo
,它只处理所有权而不是其他任何东西,并且包含一个Foo
可以从外部访问的实例,从而提供更好的关注点分离。
我实现了拥有 -Foo
像这样:
class OwningFoo : private std::unique_ptr<double[]>, public Foo {
public:
explicit OwningFoo(std::size_t size)
: std::unique_ptr<double[]>(new double[size]),
Foo(std::unique_ptr<double[]>::get()), size_(size) {
}
/* Implementation of copy and move constructors and
* assignment operators redacted. */
OwningFoo(const OwningFoo &);
OwningFoo(OwningFoo &&);
OwningFoo &operator=(const OwningFoo &);
OwningFoo &operator=(OwningFoo &&);
private:
std::size_t size_;
};
我的问题的第二部分:这是多重和私有继承的好案例吗?我在某处射自己的脚吗?
注意 ifFoo
不是成员,thanstd::unique_ptr
也不能是成员,因为它需要在之前 Foo
初始化。