web-dev-qa-db-ja.com

C ++ラッパークラスの意味は何ですか?

ラッパークラスを理解するのに少し苦労しています。誰かが適切な例を提供するのを手伝うことができれば素晴らしいでしょう。

  1. C++ラッパークラスとは何ですか?また、それを記述する状況は何ですか?
  2. どのような方法で使用されていますか?

ありがとう。

38
Mahesh

「ラッパークラス」は、リソースを「ラップアラウンド」するクラスを意味する事実上の用語です。つまり、リソースを管理します。人々がラッパーを書くとき、彼らは次のようなことをしている:

class int_ptr_wrapper
{
public:
    int_ptr_wrapper(int value = 0) :
    mInt(new int(value))
    {}

    // note! needs copy-constructor and copy-assignment operator!

    ~int_ptr_wrapper()
    {
        delete mInt;
    }

private:
    int* mInt;
};

このクラスは、intへのポインターを管理(「ラップ」)します。すべてのリソースは、クリーンさ(明示的なクリーンアップコードまたはノイズなし)および正確さ(デストラクタの実行が保証されています。クリーンアップすることを忘れず、例外を除いて安全)のために、何らかの方法でラップする必要があります。

このパターンは、Scoped-bound Resource Management(SBRM)と呼ばれますが、はるかに一般的な(ただし最も難解な)名前はResource-Acquisition is Initialization(RAII)です。上記の理由により、リソースのクリーンアップをデストラクタにバインドするという考え方です:スコープが残りを処理します。

コピーコンストラクターとコピー割り当て演算子が欠落していると言ったことに注意してください。これは Rule of Three によるものです。 (詳細な説明については、リンクされた質問を参照してください。)このルールを正しく実装する最も簡単な方法は、コピーアンドスワップイディオムを使用することです here で説明します。


通常、リソースが一意であるか、一度だけ使用される場合、リソースクリーンアップ用のラッパークラスを作成することが実用的でない場合があります。 (またはトランザクションプログラミングを使用)。これに対する解決策はscope guardと呼ばれ、それを必要とする関数内にクリーンアップコードを記述する方法です。

お気に入りの検索プロバイダー(つまり、Google)で検索するか、「プライマリ」ドキュメント here にアクセスして、詳細情報を見つけることができます。 Boostはこのために ユーティリティ を提供することに注意してください。

31
GManNickG

ラッパーは、ラップするものとは異なるインターフェースを提供することを目的とする小さなクラスです。たとえば、C APIを取得し、それを「ラップ」する1つ以上のクラスを記述して、手続き型ではなくオブジェクト指向のインターフェースを提供するのが一般的です。

10
John Zwinck

ラッパークラスを作成する状況を求めました。たとえば、さまざまな種類のカメラを使用する会社にいる場合、USB、firewireなどと言いましょう。各メーカーは、APIを介して異なる機能セットを提供します。カメラを起動し、パラメータを設定して、そこから画像ストリームを読み取ります。

ここで、会社でアプリケーションを構築するプログラマーは、さまざまなAPIのすべての特定の詳細から隔離される必要があります。今、あなたができることは、各カメラまたはよりスマートなAPIの周りにラッパークラスを書くことです。APIによって提供される既存のコードをラップする簡単な関数を持つ1つのクラスだけです。

たとえば、setFrameRate(int fps)、getImgFrame(* framebuffer)などのメンバー関数を使用して、クラスMyUSBCameraWrapperClass、MyFirewireCameraWrapperClassを設計できます。

社内のプログラマーはMyUSBCameraWrapperClass usbcamを使用できます。 usbcam.setFrameRate(30)など。ポイントを取得しますか??

7
hAcKnRoCk

ラッパークラスは、機能を別のインターフェイスでラップするクラスです。

関数f()があるとします:

void f() { std::cout << "hello\n"; }

単純なラッパークラスは

class C {
    f() { std::cout << "hello\n"; }
};

既存のコードベースが特定のインターフェイスを必要とする場合、ラッパーを作成できます。これは、アダプター設計パターンの本質です。または、その関数の状態を維持したい場合、クラスで関数をラップすることができます。あるいは、関数をクラスのコンストラクターまたはデストラクターでラップし、適切かつ自動的に適切かつ自動的に呼び出されるようにする場合があります。そしてリストは続きます。

3
wilhelmtell

私は2種類を使用します。

  1. oSが提供する機能ペアのリソースラッパー

    • UNIX:オープン/クローズ、mmap/munmap、dlopen/dlclose
    • Windows:CreateFile/DestroyHandle、CreateFileMapping/CloseHandle、LoadLibrary/FreeLibrary
  2. oSによって提供される機能の機能ラッパー

    • UNIX:書き込み、読み取り、dlsym
    • Windows:ReadFile、WriteFile、GetProcAddress

リソースラッパーは、コンパイラーがコードを生成し、コンストラクターが現在RAIIと呼ばれるものを介してコンストラクターによって作成されたリソースの破壊を心配していることを確認します。このようなクラスをベース/メンバークラスの関係を介して複雑なクラスに結合するのは簡単です。作成関数が失敗した場合、システムエラー例外がスローされ、エラーに関する豊富なエラー情報が提供されます。

単純なOS関数の代わりに、機能ラッパーが使用されます。また、障害が発生した場合、システム例外がスローされます。

このように、私のコードを使用する人は、多くのライブラリとプロセスおよびリモートマシンがある複雑な環境で何が失敗しているかを見つけるために、デバッガとデバッグコードを必要としません。

また、これらのラッパーはOSの抽象化を提供します。これらのラッパーを使用するコードは、OSの違いを心配する必要がありません。

2
user678269