C++のstd::vectorクラスを継承して新しいクラスを作って、新しいメソッドを追加する方法の紹介です。
あるプログラムの仕様
ある数字の集まりが意味を持つとします。更に、この集まりの集まりも意味を持つとします。
例えば
- 1と2の集まり
- 11と12と13の集まり
- 101と102の集まり
これらのすべての集まりの中から1つの数字、例えば11をキーに11がどの集まりに属しているかを探すプログラムを考えてみましょう。
このプログラムのロジックの検討
さきほどの前提をロジックに落とし込むことを考えます。
- 1と2の集まり・・・std::vectorに入れる
- 11と12と13の集まり・・・std::vectorに入れる
- 101と102の集まり・・・std::vectorに入れる
更に上記で作成された全てのstd::vectorを上位のstd::vectorに入れる
ここまでのロジックは容易に思いつくと思います。
このあと、例えば、11をキーにどのようにして11,12,13の集まりであるvectorを取得するかを考えないといけません。
vectorから値を取得するには、findを使えばよいのですが、単純に上位のstd::vectorからはfindでは検索できません。
このような場合に、クラスの継承を使って新しいメソッドを作成すれば簡単に目的が達成されます。
ここではstd::vectorを継承して新しいクラスを作成しています。
C++クラス継承のサンプルプログラム
それでは最初の仕様を満たすプログラムのサンプルを紹介します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include "stdafx.h" #include <vector> #include <iostream> using namespace std; class MyVector : public vector<vector<int>> { public: vector<int> getVector(int id) { for(vector<vector<int>>::iterator it = vector::begin(); it!= vector::end(); it++ ) { vector<int> v1 = *it; if(find(v1.begin(), v1.end(), id) != v1.end()) { cout << "found" << endl; return v1; } } cout << "not found" << endl; vector<int> v2; return v2; } }; int _tmain(int argc, _TCHAR* argv[]) { MyVector myVector1; vector<int> vv1, vv2; vv1.push_back(1); vv1.push_back(2); myVector1.push_back(vv1); vv1.clear(); vv1.push_back(11); vv1.push_back(12); vv1.push_back(13); myVector1.push_back(vv1); vv1.clear(); vv1.push_back(101); vv1.push_back(102); myVector1.push_back(vv1); vv1.clear(); cout << "Trying to find 11" << endl; vv2 = myVector1.getVector(11); for (vector<int>::iterator it = vv2.begin(); it != vv2.end(); ++it) { cout << *it << endl; } cout << endl; cout << "Trying to find 105" << endl; vv2 = myVector1.getVector(105); for (vector<int>::iterator it = vv2.begin(); it != vv2.end(); ++it) { cout << *it << endl; } } |
MyVectorというクラスがvector<int>を継承してvector<vector<int>>としています。
そして、このクラスの中のgetVectorというメソッドの中で、vector::begin()と親クラスのメソッドを呼び出しているところがミソです。
Javaだとsuperで呼び出すところです。
このようにvectorとかSTL(標準テンプレートライブラリ)を継承して新しいクラスを作ることができます。
実行結果は以下の通りです。
1 2 3 4 5 6 7 8 |
Trying to find 11 found 11 12 13 Trying to find 105 not found |
まとめ:クラスの継承
C++やJavaではクラスを継承して新しいクラスを作ると場合によりとても便利です。
標準のクラスを継承することも可能です。
クラスの記述方法は
C++だとchildClass : ParentClass
JavaだとchildClass extends ParentClass
です。
メソッドの呼び出し方法は
C++だとParentClass::メソッド名
Javaだとsuper.メソッド名
です。
プログラミングの無料レッスン体験
約8,000名の受講生と80社以上の導入実績のあるプログラミングやWebデザインのオンラインマンツーマンレッスンCodecamp
<Codecampの特徴>
1 現役エンジニアによる指導
2オンラインでのマンツーマン形式の講義
3大手企業にも導入されている実践的なカリキュラム
↓無料体験レッスン実施中です。
コメント
STLコンテナはデストラクタが仮想ではないため、public継承は原則としてするべきではないと思います(して良い場合というのは知りません)。
STLコンテナ(デストラクタが仮想でないクラス)を拡張したいときは、非パブリック継承かコンポジション(通常は後者)を使うのがよいと思います。
メンバ変数を追加していなければうまくいくかもしれませんが(確認していません)、原則としてやってはいけないことを書くべきではないと思います。
ほぉ。
うーん。
勉強不足でした。。。