C++Gossip:巣状カテゴリ(Nested Classes)

27688 ワード

 http://openhome.cc/Gossip/CppGossip/NestedClasses.html
カテゴリは別のカテゴリに定義することができます.このようなクラスは巣状カテゴリまたは内部カテゴリと呼ばれ、内部カテゴリは外部に包まれたカテゴリにのみ見られ、あるSlaveカテゴリが1つのMasterカテゴリに完全にサービスしている場合は、内部カテゴリに設定することができます.このようにMasterカテゴリを使用する人はSlaveの存在を知らなくてもいいです.1つの巣カテゴリは、通常「private」領域で宣言されるか、「protected」領域または「public」領域で宣言されるかのいずれかであり、宣言の例は以下の通りである.
class OuterClass { private:         class InnerClass {            //  ....         }; };
以下は巣状カテゴリの簡単な例です.
  • PointDemo.h
  • class PointDemo {
    public:
    PointDemo(int);
    ~PointDemo();

    void show();
    private:
    // Nested Class
    class Point {
    public:
    Point();
    Point(int, int);
    int x() { return _x; }
    int y() { return _y; }
    void x(int x) { _x = x; }
    void y(int y) { _y = y; }
    private:
    int _x;
    int _y;
    };

    Point **_points;
    int _length;
    };
    実際に内部カテゴリ定義を行う場合は、外部カテゴリと内部カテゴリを同時に指定する必要があります.
  • PointDemo.cpp
  • #include <iostream>
    #include "PointDemo.h"
    using namespace std;

    //
    PointDemo::Point::Point() {
    _x = 0;
    _y = 0;
    }

    //
    PointDemo::Point::Point(int x, int y) {
    _x = x;
    _y = y;
    }

    PointDemo::PointDemo(int length) : _length(length) {
    _points = new Point*[_length];
    for(int i = 0; i < _length; i++) {
    _points[i] = new Point();
    _points[i]->x(i*5);
    _points[i]->y(i*5);
    }
    }

    void PointDemo::show() {
    for(int i = 0; i < _length; i++) {
    cout << "(x, y) = ("
    << _points[i]->x() << ", "
    << _points[i]->y() << ")"
    << endl;
    }
    }

    PointDemo::~PointDemo() {
    for(int i = 0; i < _length; i++) {
    delete _points[i];
    }
    delete [] _points;
    }
    PointDemoを使用する利用者は、Pointカテゴリの存在を知る必要がなく、直接show()を呼び出すことで、Point資料を表示することができる.
  • main.cpp
  • #include <iostream>
    #include "PointDemo.h"
    using namespace std;

    int main() {
    PointDemo demo(10);
    demo.show();
    return 0;
    }
    実行結果:
    (x, y) = (0, 0) (x, y) = (5, 5) (x, y) = (10, 10) (x, y) = (15, 15) (x, y) = (20, 20) (x, y) = (25, 25) (x, y) = (30, 30) (x, y) = (35, 35) (x, y) = (40, 40) (x, y) = (45, 45)
    巣状カテゴリ構造では、外部カテゴリは内部カテゴリのプライベートメンバーにアクセスできません.内部カテゴリのプライベートメンバーにアクセスするには、外部カテゴリがfriendであることを宣言する必要があります.たとえば、次のようにします.
    class PointDemo {     ... private:    //Nested Class     class Point {         
    friend class PointDemo;
            ....     };     .... };
    同様に、内部カテゴリは外部カテゴリのプライベートメンバーにアクセスできません.プライベートメンバーにアクセスするには、friendと宣言する必要があります.たとえば、次のようにします.
    class PointDemo { public:     ...     friend class Point; private:    //Nested Class     class Point {         ....     };     .... };
    外部カテゴリの非静的メンバーにアクセスするには、直接コールではなく、アイテム、指標、または参照を使用する必要があります.内部カテゴリを1つのアーカイブに独立して定義することもできます.たとえば、次のようにします. 
  • PointDemo.h
  • class PointDemo {
    public:
    PointDemo(int);
    ~PointDemo();

    void show();
    private:

    // Nested Class
    class Point;

    Point **_points;
    int _length;
    };
  • Point.h
  • class PointDemo::Point {
    public:
    Point();
    Point(int, int);
    int x() { return _x; }
    int y() { return _y; }
    void x(int x) { _x = x; }
    void y(int y) { _y = y; }
    private:
    int _x;
    int _y;
    };
  • PointDemo.cpp
  • #include <iostream>
    #include "PointDemo.h"
    #include "Point.h"
    using namespace std;

    PointDemo::PointDemo(int length) : _length(length) {
    _points = new Point*[_length];
    for(int i = 0; i < _length; i++) {
    _points[i] = new Point();
    _points[i]->x(i*5);
    _points[i]->y(i*5);
    }
    }

    void PointDemo::show() {
    for(int i = 0; i < _length; i++) {
    cout << "(x, y) = ("
    << _points[i]->x() << ", "
    << _points[i]->y() << ")"
    << endl;
    }
    }

    PointDemo::~PointDemo() {
    for(int i = 0; i < _length; i++) {
    delete _points[i];
    }
    delete [] _points;
    }
  • Point.cpp
  • #include "PointDemo.h"
    #include "Point.h"

    PointDemo::Point::Point() {
    _x = 0;
    _y = 0;
    }

    PointDemo::Point::Point(int x, int y) {
    _x = x;
    _y = y;
    }