既存のクラスのメンバ関数呼出しを乗っ取るような方法はありません。 特定の機能のみを上書きしたい場合には継承を使うのは妥当な方法です。 一方で、 C++ の各種コンテナクラスはデストラクタが virtual
ではないためにスライシングの問題に晒されてしまうことから public
継承は避けるのが常識です。
自分で使うだけならスライシングが起こらないように注意深く扱えば問題はありませんが、やはり意図せず問題のある状況になってしまうことは防止したいですね。 問題になるのは public
継承ですから、 private
継承してしまうという方法もあります。
このとき、 using
で基底のメンバを指定することでそのまま派生クラスのメンバとして公開することが出来るので、あらためてコンテナと同等のものを実装する必要はありません。 コンテナは多機能ですから、名前を羅列するだけでも面倒くさくはあるのですが。
cpp
1#include <iostream>
2#include <vector>
3
4template <typename T>
5class MyVector : private std::vector<T> {
6public:
7 // 使いたい基底クラスのメンバを using で指定する
8 using std::vector<T>::operator[];
9 using std::vector<T>::size;
10 // (省略......)
11
12 void push_back(const T& x) {
13 std::cout << "throw event!" << std::endl; // ここに通知の処理を入れる
14 std::vector<T>::push_back(x);
15 }
16};
17
18int main() {
19 MyVector<int> v;
20 v.push_back(99); // オーバーライドした push_back にアクセスできる
21
22 // using したものは基底クラスのメンバが使われる
23 std::cout << "v.size()=" << v.size() << std::endl;
24 std::cout << v[0] << std::endl;
25 return 0;
26}
private
継承で基底のメンバを使う方法だけを説明しましたが、ここまで出来ればオブザーバと結びつける処理などは定型的なものだと思うので省略します。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/08 09:47