建設と破壊に関するいくつかの考慮事項

  1. 変数を初期化する必要があります。初期化には初期化リストを使用してみてください。初期化されていない場合、変数の値はランダムに不確実になります。
class Point {
    
    
    int x;
    int y;
};
// 改进之后后
class Point {
    
    
   public:
    Point(int x, int y) : _x(x), _y(y) {
    
    }

   private:
    int _x;
    int _y;
};
  1. プライベートデストラクタであるクラスオブジェクトは、スタックにスペースを割り当てることはできません。ヒープにのみ割り当てることができますが、削除によって直接解放することはできません。
#include <iostream>
using namespace std;

class Point {
    
    
   public:
    Point(int x, int y) : _x(x), _y(y) {
    
    }
    void destory() {
    
     delete this; }
   private:
    ~Point() {
    
    }

   private:
    int _x;
    int _y;
};

int main(int argc, char const *argv[]) {
    
    
    //Point p(1, 2);// error
    Point *p1 = new Point(1, 2);
    //delete p1;//error
    p1.destory();
    return 0;
}
  1. 新規ブロックと削除、オブジェクトはスタックにのみ割り当てることができます
#include <iostream>
using namespace std;

class Point {
    
    
   public:
    ~Point() {
    
    }
    Point(int x, int y) : _x(x), _y(y) {
    
    }
    // 删除或者私有new 和 delete
    void* operator new(size_t size) = delete;
    void operator delete(void* ptr) = delete;
    //    private:
    //     void* operator new(size_t size);
    //     void operator delete(void* ptr);

   private:
    int _x;
    int _y;
};

int main(int argc, char const* argv[]) {
    
    
    Point* p1 = new Point(1, 2);//error
    delete p1;
    return 0;
}
  1. 多態的な基本クラスは仮想デストラクタとして宣言されています。宣言されていない場合、メモリリークが発生する可能性があります。コードは次のとおりです。
    逆に、仮想デストラクタを設定しないでください。冗長メモリが発生します。
#include <iostream>
using namespace std;

class Base {
    
    
   public:
    Base() {
    
     a = new char[100]; }
    ~Base() {
    
    
        cout << __func__ << endl;
        delete[] a;
    }

   private:
    char* a;
};
class Derived : public Base {
    
    
   public:
    Derived() {
    
     b = new char[100]; }
    ~Derived() {
    
    
        cout << __func__ << endl;
        delete[] b;
    }

   private:
    char* b;
};

int main(int argc, char const* argv[]) {
    
    
    Base* d = new Derived();
    delete d;
    return 0;
}

出力:

[root@localhost poco_demo]# g++ tt.cpp -std=c++11 -o tt
[root@localhost poco_demo]# ./tt
~Base
  1. デストラクタで例外をスローしないでください。これにより、メモリ障害などのエラーが発生する可能性があります。正しいアプローチは、これらのエラーをキャッチして処理し、レイヤーごとに破棄するのではなく、破壊を正常に終了させることです。

  2. 関数を破棄して構築するのではなく、仮想関数を使用してください。仮想関数は仮想関数テーブルを介して制御され、クラスは仮想関数テーブルのポインターを介して仮想関数テーブルにアクセスします。仮想関数テーブルポインタはメンバー変数として使用され、構築中に初期化され、破棄中にそのライフサイクルを終了します。継承システムでは、これはより混乱します。

  3. 仮想関数はあまり意味がないため、プライベートにしないでください。_vptrを取得している限り、仮想関数テーブルにアクセスしてから、仮想関数へのプライベートアクセスをバイパスできます。

おすすめ

転載: blog.csdn.net/niu91/article/details/109938875