C ++入門書15.8で、作者が「ハンドルクラスと継承」について話したとき、彼は次のように述べました。
C ++の一般的な手法は、いわゆるカバークラスまたはハンドルクラスを定義することです。ハンドルクラスは、基本クラスへのポインタを格納および管理します。そのポインタが指すオブジェクトのタイプは異なります。ベースタイプまたは派生タイプのオブジェクトを指すことができます。ユーザーは、ハンドルを介して継承階層の操作にアクセスします。ハンドルはそのポインターを使用してこれらの操作を実行するため、仮想メンバーの動作は、ハンドルが実際にバインドされているオブジェクトの種類に応じて実行時に変化します。したがって、ハンドルのユーザーは動的な動作を取得しますが、ポインターの管理について心配する必要はありません。
上記は私へのスマートポインタのように聞こえます。ただし、この「ハンドル」の使用法は少し異なります。
Handle h(Derived()); // noticed a derived object, not a pointer is used to initialize the handle!
h->func();
そして、ハンドルの後者の実装(以下に表示)は、作成者がハンドルについてコメントしていることを証明します。
ハンドルのユーザーには、ハンドルをアタッチできる独自のオブジェクトを作成してもらいたいと思います。ハンドルは、適切なタイプの新しいオブジェクトを割り当て、ユーザーのオブジェクトをその新しく割り当てられたオブジェクトにコピーします。そうすれば、ハンドルクラスがオブジェクトを所有し、オブジェクトに接続されている最後のハンドルがなくなるまでオブジェクトが削除されないことを保証できます。
コード:
public:
Base(){}
virtual int func(std::size_t n) const {}
virtual Base* clone() const { return new Base(*this); }
};
class Derived : public Base {
public:
Derived():Base(){}
int func(std::size_t) const; // redefine
Derived* clone() const { return new Derived(*this); }
};
class Handle {
public:
Handle(const Base &b):p(b.clone()), use(new std::size_t(1)) { }
private:
Base *p;
std::size_t *use; // pointer to shared use count
};
私の質問は、これは本当にC ++またはOOでのハンドルの典型的な意味ですか?ハンドルは、内部でuse-countを保持する単なる基本型のスマートポインター、またはより一般的には、システムがそれが何を指し、それをどう処理するかを知っている魔法のint型である可能性があると思いました。ここでこのハンドルがユーザーオブジェクトのコピーを作成し、そのコピーに基づいてuse-countを実行する必要があるのはなぜですか?