質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2467閲覧

STLに対してObserverパターンを実現するには?

KureteRubyLua

総合スコア206

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2017/06/07 11:12

例えばstd::vectorでpush_back等の関数が呼ばれた時に同時に別の関数を呼び出したいのですが、どうやって実現すればいいのか分かりません。

STLのクラスを継承するわけにはいきませんし、STLの同様の機能を持つクラスを作るというのも非常に手間です。

何とかしてSTLでObserverパターンを使えるようにするにはどうすればいいのでしょうか?

よろしくお願いします。

SaitoAtsushi👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

既存のクラスのメンバ関数呼出しを乗っ取るような方法はありません。 特定の機能のみを上書きしたい場合には継承を使うのは妥当な方法です。 一方で、 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/07 12:06

SaitoAtsushi

総合スコア5437

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KureteRubyLua

2017/06/08 09:47

どうも有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問