C++構築/解析関数

3087 ワード

コンストラクタ初期化リスト
クラスのメンバー変数にクラスが存在する場合、メンバークラスにはパラメータまたはデフォルトのコンストラクション関数がなく、クラスのオブジェクトを作成するときにエラーが発生します.これは初期化リストを使用する必要があります.必要なメンバー変数を初期化します.
  • 初期化リストの初期化順序は、メンバー変数の定義順序で初期化され、最後に構築関数内部に実行される.
  • 解析関数の実行順序は,構築時とは逆である.
  • //Rect.h
    #include "Point.h"
    class Rect {
    private:
       int index;
       Point p2;
       Point p1;
    public:
       Rect(int index, int x1, int x2);
       ~Rect();
       void print();
    };
    
    //Rect.cpp
    Rect::Rect(int index, int x1, int x2):p1(x1,0,"name is p1"),p2(x2,0,"name is p2") {
       this->index=index;
    }
    

    コピーコンストラクタ呼び出しタイミング
  • あるオブジェクトは別のオブジェクトPoint p2 = p1;
  • に割り当てられる.
  • 構造関数においてパラメータとしてPoint p3(p1);
  • に伝達する.
  • 関数呼び出し時にクラスがパラメータとして存在し,実パラメータがパラメータに参照される.
    void printPoint(Point point) {
        cout << point.getX() << " " << point.getY() << endl;
    }
    
  • 関数が値をオブジェクトに返す場合(コンパイラは最適化され、呼び出されない可能性があります).
    Point getPoint() {
      Point p(10, 20);
      return p;
    }
    

  • Point.h
    class Point {
    private:
        int x;
        int y;
    public:
        Point(int x, int y);
    
        Point(int x);
    
        Point();
    
        int getX() const;
    
        void setX(int x);
    
        int getY() const;
    
        void setY(int y);
    
        virtual ~Point();
    
        Point(const Point&);
    };
    

    Point.cpp
    #include "iostream"
    #include "Point.h"
    
    using namespace std;
    
    int Point::getX() const {
        return x;
    }
    
    void Point::setX(int x) {
        Point::x = x;
    }
    
    int Point::getY() const {
        return y;
    }
    
    void Point::setY(int y) {
        Point::y = y;
    }
    
    Point::Point(int x, int y) : x(x), y(y) {
        this->x = x;
        this->y = y;
        cout << "Point(x=" << x << ",y=" << y << ")" << endl;
    }
    
    Point::Point(int x) : x(x) {
        this->x = x;
        cout << "Point(x=" << x << ")" << endl;
    }
    
    Point::Point() {
        cout << "Point()" << endl;
    }
    
    Point::~Point() {
        cout << "~Point()" << endl;
    }
    
    Point::Point(const Point &point) {
        this->x = point.x + 100;
        this->y = point.y + 100;
        cout << "Point(const Point &point)" << endl;
    }
    

    結果:
    Point(x=1,y=2)
    ----
    Point(const Point &point)
    ----
    Point(const Point &point)
    ----
    Point(const Point &point)
    101 102
    ~Point()
    ----
    Point(x=1,y=2)
    ~Point()
    ~Point()
    ~Point()
    ~Point()
    

    浅いコピー
  • のデフォルトのcopy構造関数と付与操作は、浅いコピーです.値はメンバー変数の値をコピーします.メンバー変数にポインタが存在する場合、メモリ領域が解放されると、野ポインタの問題が発生します.この場合、copy構造関数を書き換える必要があります.例:
  • Point::Point(const Point &point) {
        this->x = point.x + 100;
        this->y = point.y + 100;
        if (point.getName() != NULL) {
            int len = strlen(point.getName());
            this->name = (char *) malloc((sizeof(char)) * (len + 1));
            strcpy(this->name, point.getName());
        }
        cout << "Point(const Point &point)" << endl;
    }