- 変数を初期化する必要があります。初期化には初期化リストを使用してみてください。初期化されていない場合、変数の値はランダムに不確実になります。
class Point {
int x;
int y;
};
// 改进之后后
class Point {
public:
Point(int x, int y) : _x(x), _y(y) {
}
private:
int _x;
int _y;
};
- プライベートデストラクタであるクラスオブジェクトは、スタックにスペースを割り当てることはできません。ヒープにのみ割り当てることができますが、削除によって直接解放することはできません。
#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;
}
- 新規ブロックと削除、オブジェクトはスタックにのみ割り当てることができます
#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;
}
- 多態的な基本クラスは仮想デストラクタとして宣言されています。宣言されていない場合、メモリリークが発生する可能性があります。コードは次のとおりです。
逆に、仮想デストラクタを設定しないでください。冗長メモリが発生します。
#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
-
デストラクタで例外をスローしないでください。これにより、メモリ障害などのエラーが発生する可能性があります。正しいアプローチは、これらのエラーをキャッチして処理し、レイヤーごとに破棄するのではなく、破壊を正常に終了させることです。
-
関数を破棄して構築するのではなく、仮想関数を使用してください。仮想関数は仮想関数テーブルを介して制御され、クラスは仮想関数テーブルのポインターを介して仮想関数テーブルにアクセスします。仮想関数テーブルポインタはメンバー変数として使用され、構築中に初期化され、破棄中にそのライフサイクルを終了します。継承システムでは、これはより混乱します。
-
仮想関数はあまり意味がないため、プライベートにしないでください。_vptrを取得している限り、仮想関数テーブルにアクセスしてから、仮想関数へのプライベートアクセスをバイパスできます。