トップ->C++入門

あなたは

人目のC++(C)言語入門受講生です。

C++入門内検索

目次
C++入門〜トップ
C言語入門〜トップ
0. はじめに

1. オブジェクト指向とは?
   1. オブジェクト指向とクラス
   2. 継承
   3. カプセル化
   4. ポリモーフィズム

2. ストリーム
   1. 出力
   2. マニピュレータ
   3. 入力
   4. ファイル
   5. 練習問題1
   6. 文字列
   7. 練習問題2

3. C++の新しい文法
   1. 新しい型bool
   2. デフォルト引数
   3. newとdelete
   4. 参照型
   5. const
   6. 変数の宣言
   7. 例外
   8. オーバーロード
   9. テンプレート関数
   10. 名前空間

4. クラス
   1. クラスとは
   2. クラスの宣言
   3. クラスの実装
   4. コンストラクタとデストラクタ
   5. クラスの使用法
   6. 例題)スタッククラス
   7. テンプレートクラス
   8. 練習問題
   9. 参照型
   10. 代入演算子
   11. コピーコンストラクタ
   12. 構造体
   13. メンバー変数の初期化
   14. 内部クラス
   15. 無名クラス
   16. 無名共用体
   17. 演算子の作り方
   18. friend
   19. 練習問題
   20. クラス変数(静的変数)
   21. 静的関数
   22. クラスと関数ポインタ

5. クラスの包含
   1. 包含とは
   2. クラスの作成・破壊
   3. メンバーイニシャライザ
   4. ポインタによる包含
   5. 参照による包含
   6. 練習問題

6. 継承
   1. 継承とは
   2. スーパークラスのコンストラクタ
   3. 継承とキャスト
   4. スコープ
   5. クラスの作成・破壊
   6. 派生の種類
   7. 仮装関数
   8. 純粋仮装関数
   9. 仮装デストラクタ
   10. 例題)例外クラス
   11. V-table(VF-table)
   12. 例題)お絵かきソフト
   13. 継承と包含
   14. 多重継承
   15. 多重継承の用途
   16. 仮想クラス
   17. 実行時型情報(RTTI)
   18. dynamic_cast

7. STL
   1. STLとは
   2. STLの歴史
   3. STLの構成
   4. コンテナ
   5. vector
   6. イタレーター
   7. クラスとSTL
   8. list
   9. queue
   10. deque
   11. priority_queue
   12. stack
   13. map
   14. mutimap
   15. set
   16. multiset
   17. bitset
   18. アルゴリズム
   19. basic_string
   20. コンテナを作ろう
   21. アルゴリズムを作ろう
   22. 配列とアルゴリズム

8. その他
   1. 変数名について

9. その後は
   1. ヒューマンアカデミー C言語講座
   2. el school C言語講座


・ トップページに戻る



・ トップページに戻る

トップ-> C++入門:4章 クラス-> 内部クラス

←前ページへ :  トップへ :  次ページへ→

14. 内部クラス

  内部クラスとは、あるクラスの中で定義されたクラスのことを言います。
class OuterClass{
    class InnerClass{
    public:
        int member;
    };

    int member;
    InnerClass in;

    OuterClass( int n ){
        member = n;
    }
};
  内部クラスだけでなく、内部構造体、内部共用体も作ることもできます。

  内部クラスは、あるクラスの内部でのみ使用するデータとして使われることが多いです。 以下の例は、マップ(辞書)クラスの例です。マップでは、キーと呼ばれるデータ検索の 元となるデータと、バリューというデータ本体を持ちます、マップに登録する際には キーとバリューを格納します。検索する際には、キーを引数にとり、バリューを返します。 つまり、Mapクラス内でのみ使用するデータとして、キーとバリューからなるデータクラスを 作成します。

  アプリケーションとしては、英和辞書です。したがってキーが英語、バリューは その日本語訳になります。文字列を使用するので、未完成ではありますが、簡単な stringクラスを一緒に作ってみました。

map.h
///////////////////////////////////////////////////////////////////////////
//
//    テンプレートマップクラス定義
//


// 2重取り込みを防止する
#ifndef MAP_H
#define MAP_H
#include <iostream>
using namespace std;

//////////////////////////////////////////////////////////////////////////////
// マップクラス

template<class Key, class Value>
// 内部クラス
class Map {
    class Data{
    public:
        Key   key;
        Value value;
    };


public:

    // コンストラクタ
    Map( int sz = 100 ){
        size  = 0;
        mapdata = new Data[sz] ;
    }

    // コピーコンストラクタ
    Map( const Map<Key, Value>& src ){
        copy( src ) ;
    }

    // デストラクタ
    // Stack オブジェクトが削除される時に自動的に呼び出される
    ~Map(){
        //スタック本体を削除する
        delete [ ] mapdata ;
    }

    // データの追加
    void add( const Key& k, const Value& v ){
        mapdata[size].key   = k;
        mapdata[size].value = v;
        size++;
    }


    // データの検索
    bool get( const Key& k, Value* v ){
        for( int i = 0 ; i < size ; i++ ){
            if( mapdata[i].key == k ){
                *v = mapdata[i].value;
                return true;
            }
        }
        return false;
    }

    // 現在の項目数を返す
    int get_size(){
        return size;
    }

    // 代入演算子
    Map<Key, Value>& operator=( const Map<Key, Value>& src ){
        // 自己代入でなければ
        if( &src != this ){
            // 現在自分が保有しているスタックを削除する
            delete [] mapdata;

            // コピー元の配列をコピーする
            copy( src );
        }
        return *this;
    }

private:
    // 代入演算子とコピーコンストラクタから呼ばれる
    // コピーもとのメンバー変数size、spをコピーし、
    // 新しい配列を割り当て、配列の中身をコピーする
    void copy( const Map<Key, Value>& src ){
        // サイズをコピーする
        size  = src.size;

        // サイズ分の配列を作る
        mapdata = new Data[size];

        // 配列の中身をコピーする
        for( int i = 0 ; i < size ; i++ )
            mapdata[i] = src.mapdata[i];
    }

    ////////////////////////////////////////////////////
    // 管理情報

    // 要素数
    int size;

    // データ
    Data *mapdata;
};

#endif // MAP_H

string.h
/////////////////////////////////////////////////////////////////////////// // // 文字列クラス定義 // // 2重取り込みを防止する #ifndef STRING_H #define STRING_H #include<string.h> #include <iostream> using namespace std; ////////////////////////////////////////////////////////////////////////////// // 文字列クラス class string{ char* p; void copy( const char* src ){ int len = strlen(src); pQ = new char[len+1]; strcpy(p, src); } public: // コンストラクタ string(const char* src){ copy(src); } // コピーコンストラクタ string( const string& src){ copy(src.p); } // デフォルトコンストラクタ string(){ p = new char[1]; *p = '\0'; } // デストラクタ ~string(){ delete p; } // 比較演算子 bool operator==( const string& a )const{ return strcmp( p, a.p ) == 0; } // 代入演算子 string& operator=( const string& src ){ if( &src != this ){ delete p; copy(src.p); } return *this; } // ストリーム出力 friend ostream& operator<<( ostream& os, const string& s ); }; // ストリーム出力 ostream& operator<<( ostream& os, const string& s ){ os << s.p; return os; } #endif // STRING_H
main.cpp
#include <iostream> #include <process.h> #include "map.h" #include "string.h" using namespace std; void main(){ Map<string, string> map(6); map.add( "white", "白" ); map.add( "black", "黒" ); map.add( "red", "赤" ); map.add( "yellow", "黄色" ); map.add( "green", "緑" ); map.add( "blue", "青" ); char buffer[512]; while( cin >> buffer ){ string eng = buffer; string jap; if( map.get( eng, &jap ) ) cout << eng << "\t" << jap << endl; else cout << eng << "\t" << "未登録です" << endl; } }
C:\>maptest
red
red     赤
white
white   白
yellow
yellow  黄色
pink
pink    未登録です
^Z

C:\>

  上記の例にはまだ解説していない「friend」と 演算子の作り方がでてきていますが、これらについては後述します。



←前ページへ :  トップへ :  次ページへ→