- 变量要初始化,初始化尽量使用初始化列表。如果不初始化,变量的值是随机不确定的。
class Point {
int x;
int y;
};
// 改进之后后
class Point {
public:
Point(int x, int y) : _x(x), _y(y) {
}
private:
int _x;
int _y;
};
- 私有析构函数,类对象不能在栈上分配空间. 只能在堆上分配,但不能delete直接释放。
#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;
}
- 屏蔽new和delete, 对象只能在栈上分配
#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;
}
Output:
[root@localhost poco_demo]# g++ tt.cpp -std=c++11 -o tt
[root@localhost poco_demo]# ./tt
~Base
-
不要在析构函数中抛出异常,这样可能会导致内存无法释放等错误。正确的做法是,捕获并处理掉这些错误,让析构正常结束,而不是一层层抛出。
-
不要再析构和构造函数,使用虚函数。虚函数是通过虚函数表控制,类通过虚函数表指针,访问虚函数表。虚函数表指针作为一个成员变量,在构造时初始化,析构时结束生命周期。在继承体系中,这样做会更混乱。
-
不要私有一个虚函数,因为这没什么意义。只要拿到_vptr,就可以访问虚函数表,进而绕过private访问虚函数。