1

私はいくつかの (私の意見では) かなり具体的な所有権要件を持っています: 基本的に double の配列が特定の方法 (いくつかのかなり大きな行列の連結) であると解釈するクラスがあり、それを解釈する C ライブラリと通信したいと考えています。別の方法 (非常に長い数学的ベクトル)。場合によっては、C ライブラリによってコールバックに渡されるポインターを解釈したい場合があります。つまり、所有権を取得する必要はありません。その場合、コピーは非常に非現実的です。それ以外の場合は、バッファを自分で割り当てて、自分で C ライブラリに渡したいと思います。その場合、私のコードはバッファを所有しています。

次のように、double 配列を行列として解釈する「構成要素」を作成しました (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. */
};

コピーと移動は禁止されているため、インスタンスが誤って作成されたり、バッファー自体よりも長生きする場所に移動されたりすることはありません。もちろん、そのようなインスタンスを意図的に作成することは、ポインターをどこかに直接渡すことで可能ですが、ソース内でより簡単に見つけることができます。

私の質問の最初の部分: 「バッファの所有権で強化された」をのサブクラスにすることは理にかなっていますか?FooFoo

所有している状態であらゆる操作Fooが可能でFoo、さらに、所有している状態Fooで自由にコピー、移動できます。リスコフの置換原理が満たされているような匂いがします。メンバー変数にデリゲートすることで、owningを処理できます。FooまたFoo、owning で多数のメソッドを記述せずに構文的に同じ方法で処理できることは、非常に快適です。Foo

一方、所有権のみを処理し、外部からアクセスできるFooインスタンスを含む owner-of- insteadが存在する可能性があり、懸念事項をより適切に分離できます。Foo

私はowning-を次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_;
};

私の質問の 2 番目の部分:これは複数のプライベートな継承の良いケースですか? どこかで自分の足を撃っていますか?

がメンバーでない場合は、 の前に初期化する必要があるため、Fooメンバーにもなれないことに注意してください。std::unique_ptr Foo

4

1 に答える 1

1

私のやり方は、所有権の問題をさらに押し下げることです。Foo にはバッファーがあり、そのバッファーが破棄されたときにそのバッファーをクリーンアップする方法を知っています。std::shared_ptr には、たとえば、その目的で使用できる destroy コールバックがあります。これは、この特定のインスタンスを削除する方法をスマート ポインターに認識させるという受け入れられたパターンを示しています。

実際には、総所有権が追跡されるように、おそらく共有バッファーが必要です。何が起こっているかを知っている他の場所で「私ではない」ように暗黙的にプログラミングすることは、かなり脆弱です。

「所有権フラグの確認」は、使用できる一般的な堅牢な実装を持つ「私が最後の/唯一の所有者である」という特殊なケースです。

あなたが言及したひねりの中で、バッファを所有するCコードは、クラスの存続期間とどのように調整されますか? 悪いように聞こえますが、クラスがバッファーを所有していないことを (適切にカプセル化された方法で) 認識しても、C コードがインスタンスがいつそれを使用したかを認識できないという問題は変わりません。

于 2014-09-16T06:02:31.693 に答える