C++基礎学習-1

4230 ワード

友元関数:
関数名の前にfriendキーを付けます.
classの異なるメンバーには、public、protected、privateの3つの階層の内部保護があります.メンバーがprotectedおよびprivateの場合、それらは存在するclass以外の部分から参照できません.外部関数がclassにアクセスできるprivateおよびprotectedメンバーを実装するには、class内部でキーワードfriendで外部関数のプロトタイプを宣言し、関数がclassを共有できるメンバーを指定する必要があります.
  #include <iostream.h>
    
    class CRectangle {
        int width, height;
      public:
        void set_values (int, int);
        int area (void) {return (width * height);}
        friend CRectangle duplicate (CRectangle);
    };
    
    void CRectangle::set_values (int a, int b) {
        width = a;
        height = b;
    }
    
    CRectangle duplicate (CRectangle rectparam) {
        CRectangle rectres;
        rectres.width = rectparam.width*2;
        rectres.height = rectparam.height*2;
        return (rectres);
    }
    
    int main () {
        CRectangle rect, rectb;
        rect.set_values (2,3);
        rectb = duplicate (rect);
        cout << rectb.area();
    }
			

Friend classes
friend関数を定義できるように、1つのclassが別のfriendであることを定義して、2番目のclassが最初のclassのprotectedとprivateメンバーにアクセスできるようにすることもできます.
// friend class
    #include <iostream.h>
    
    class CSquare;

    class CRectangle {
        int width, height;
      public:
        int area (void) {return (width * height);}
        void convert (CSquare a);
    };
    
    Class CSquare {
      private:
        int side;
      public:
        void set_side (int a){side=a;}
        friend class CRectangle;
    };
    
    void CRectangle::convert (CSquare a) {
        width = a.side;
        height = a.side;
    }
    
    int main () {
        CSquare sqr;
        CRectangle rect;
        sqr.set_side(4);
        rect.convert(sqr);
        cout << rect.area();
        return 0;
    }

仮想メンバー(Virtual members)
キーワードvirtualの役割は、ベースクラスのポインタを使用するときに、サブクラスのベースクラスと同名のメンバーが適切なときに呼び出されることです.
ベースクラスでメンバーを定義してサブクラスにドリルダウンする場合は、ポインタを使用して対応するオブジェクトを操作できるように、その前にキーワードvirtualを追加する必要があります.
#include <iostream.h>
class CPolygon {
    protected:
        int width, height;
    public:
        void set_values (int a, int b)  {
            width=a;
            height=b;
        }
        virtual int area (void) { return (0); }
};
class CRectangle: public CPolygon {
    public:
        int area (void) { return (width * height); }
};
class CTriangle: public CPolygon {
    public:
        int area (void) {
            return (width * height / 2);
        }
};
int main () {
    CRectangle rect;
    CTriangle trgl;
    CPolygon poly;
    CPolygon * ppoly1 = ▭
    CPolygon * ppoly2 = &trgl;
    CPolygon * ppoly3 = &poly;
    ppoly1->set_values (4,5);
    ppoly2->set_values (4,5);
    ppoly3->set_values (4,5);
    cout << ppoly1->area() << endl;
    cout << ppoly2->area() << endl;
    cout << ppoly3->area() << endl;
    return 0;
}

現在、この3つのクラス(CPolygon、CRectangle、CTriangle)には同じメンバーがいます.width、height、set_values()とarea()です.
area()がvirtualと定義されたのは,後でサブクラスで細分化されたためである.コード種でこのキーワード(virtual)を削除してからこのプログラムを実行すると、3つのポリゴンの面積計算結果は20,10,0ではなく0になります.これは、キーワードvirtualがないため、プログラム実行は、実際のオブジェクトの使用に応じて対応するarea()関数(すなわち、CRectangle::area()、CTriangle::area()およびCPolygon::area())を呼び出さず、代わりに、CPolygon::area()をすべて呼び出す.これらの呼び出しはCPolygonタイプのポインタによって行われるためである.
抽象ベースクラス(Abstract base classes)
抽象クラス(abstract base class)では、関数を定義せずに、関数宣言の後に=0(0に等しい)と書くことができます.
クラスCPolygonは次のように書くことができます.
//abstract class CPolygon
class CPolygon {
    protected:
        int width, height;
    public:
        void set_values (int a, int b) {
            width=a;
            height=b;
        }
        virtual int area (void) =0;
};

関数の具体的な実装の代わりにvirtual int area(void)に=0を加算する方法を示した.この関数を純仮想関数(pure virtual function)と呼び、純仮想関数を含むすべてのクラスを抽象ベースクラス(abstract base classes)と呼ぶ.
抽象ベースクラスの最大の違いは、インスタンス(オブジェクト)が存在しないことですが、ポインタを定義できます.
そのため、このような声明は次のとおりです.CPolygon poly;は合法ではありません.
ただし、ポインタ:CPolygon * ppoly1;
CPolygon * ppoly2

完全に合法的な親ポインタは、子オブジェクトを指すことができます.親では、このポインタは親のすべてのメソッドを使用して、どの子を管理する必要はありません.