3

この質問には関係ありませんが、画像処理ライブラリである OpenCV ライブラリで C++ を使用しています。現在、私はデザインの決定を下しています。

C ライブラリである OpenCV には、そのデータ構造 (CvMat など) が構造体として宣言されています。作成するには cvCreateMat などの関数を使用し、解放するには cvReleaseMat などの関数を使用します。C++ プログラマーとして、cv_scopedスコープ外になったときに cvReleaseMat を自動的に呼び出す特別なクラスを作成しました ( のようにboost::scoped_ptr)。

私が今気付いているのは、ケースでも使用できればいいのにということauto_ptrですshared_ptr。時間の無駄は言うまでもなく、自分自身cv_auto_ptrcv_shared_ptrクラスのコードを書くのは悪い考えだと思います。それで解決策を探していて、3つの可能性を思いつきました。

まず、作成済みの cv_scoped クラスを使用できます。名前を に変更してからcv_ptr、次のようなスマート ポインターを使用しますstd::auto_ptr<cv_ptr>。ただし、これに関する厄介なことは、常に 2 回逆参照する必要があることです。

std::auto_ptr<cv_ptr> matrix(cv_ptr(cvCreateMat(320, 240, CV_32FC3)));
cvPow(matrix.get()->get()); // one get for the auto_ptr, one for the cv_ptr

暗黙的な変換を宣言できるように見えることはわかっていますが、実際にはできませんでした.OpenCVの関数のほとんどにはパラメータ void* があるため、暗黙的な変換は呼び出されません. 二重逆参照を行う必要のない方法でこれを行う方法が本当に欲しいです。

第二に、どうにかしてオーバーライドすることができoperator deleteました。これを CvMat (および他のいくつかの) 型に適用したいだけなので、グローバル演算子 delete をオーバーライドしたくありません。ただし、ライブラリを変更できないoperator deleteため、CvMat 構造体に追加できません。したがって、これがどのように機能するかはわかりません。

第三に、自分のauto_ptr, scoped_ptr, and を書き直すことができましたshared_ptr。大規模なクラスではないので、それほど難しくはありませんが、これは設計が悪いと感じています。私がこれを行うとしたら、おそらく次のようなことをするでしょう。

class cv_auto_ptr {
public:
  cv_auto_ptr();
  ~cv_auto_ptr();

  // each method would just be a proxy for the smart pointer
  CvMat* get() { return this->matrix_.get()->get(); }
  // all the other operators/methods in auto_ptr would be the same, you get the idea

private:
  auto_ptr<cv_ptr> matrix_; // cv_ptr deletes CvMat properly
}

私の状況であなたはどうしますか?これを理解するのを手伝ってください。

4

3 に答える 3

4

auto_ptr は実際には C++ クラスの RAII 用に設計されており、コンストラクト/デストラクタを使用して、おそらく使用すべきではない (しかし使用できる) ものにプッシュしています。

とにかく、毎回動的に割り当てることなく、通常のスタック変数であるかのように C++ オブジェクトを使用できるようにしたいと思いませんか?

問題の標準的な解決策は、コンストラクター/デストラクターを使用してラッパーを作成することです。
しかし、C関数で使用できるようにするには、内部キャスト演算子を追加するだけで、C関数に渡されたときに自動的にCオブジェクトに変換されます

ラッパー クラスを記述します。

class Mat
{
    CvMat* impl;
    public:
        Mat(/* Constructor  Arguments */)
        {
            impl = cvCreateMat(/* BLAH */);
        }
        ~Mat()
        {
            cvReleaseMat(impl);
        }
        operator CvMat*()
        {   // Cast opertator. Convert your C++ wrapper object into C object
            // when you use it with all those C functions that come with the
            // library.

            return impl;
        }
};

void Plop(CvMat* x)
{   // Some C function dealing with CvMat
}

int main()
{                            // Don't need to dynamically allocate
    Mat                  m;  // Just create on the stack.
    Plop(m);                 // Call Plop directly

    std::auto_ptr<Mat>   mP(new Mat);
    Plop(*mP);
}
于 2009-01-31T17:16:29.240 に答える