类设计者的核查表读书笔记:
每个好的飞行员都有个核查表。核查表不是任务清单,它用途帮助你回忆起可能会忘记的事情。这些问题没有确切的答案,关键是提醒你思考他们。
1:你的类需要一个构造函数吗?(构造函数来隐藏他们的内部工作方式)
2:你的数据成员是私有的吗?
Template calss vector{
Public:
Int length; //公有数据成员,这个设计令人质疑
// 。。。
}
3:你的类需要一个无参的构造函数吗?
class Point P
{
public:
Point(int p, int q):x(p), y(q) {}
//...
private:
int x, y;
}
如果没有 Point p; //错误:没有初始化
Point pa[100] //错误
4:是不是每个构造函数初始化所有的数据成员?
5:类需要析构函数吗?
应该问:是否分配了资源,这些资源又不会有成员函数自动释放。
6:类需要一个虚析构函数吗?
决不会用做基类的类是不需要虚析构函数的。任何需函数只在继承的情况下才有用。
struct B{
int s;
virtual ~B() {}
};
struct D:B{
int t;
};
int main()
{
B *bp = new D; //这里没有问题,但是。。。
delete bp; // 除非B有个虚析构函数,否则将调用错误的析构函数。
}
VC中没有错误。
7:你的类需要复制构造函数吗?
8:你的类需要一个赋值操作符吗?
9:你的赋值操作符能正确的将对象赋给对象本身吗?
class String {
public:
String & operator=(const String&s);
//各种相同的其他成员
private:
char* data;
};
//很明显但不正确的实现
String& String::operator =(const String&s)
{
delete [] data;
data = new char[strlen(s.data)+1];
strcpy(data, s.data);
return *this; // s和*s指向同样的对象
}
//正确的实现方法1
String& String::operator ==(const String& s)
{
if(&s != this) {
delete [] data;
data = new char[strlen(s.data)+1];
strcpy(data, s.data);
}
return *this;
}
//正确的实现方法2
String& String::operator ==(const String&s)
{
char *newdata = new char[strlen(s.data)+1];
strcpy(newdata,s.data);
delete [] data;
data = newdata;
return *this;
}
10:你的类需要定义关系操作符吗?
11:删除数组时你记住了用delete[]吗?
12:记得在复制构造函数和赋值操作符类型中加上const了吗?
X::X(X&)
X::X(const X&)
X::operator=(const X&);
13:如果函数有引用参数,应该是const引用吗?
Complex operator+(Complex& x, Complex& y);
Complex operator+(const Complex& x, comst Complex&y);
14:记得适当地声明成员函数为const了吗?
template class Vector {
public:
int length(); //得到长度 (错误)
int length(int); //设置长度,返回前一个
//。。。
}
template class Vector {
public:
int length() const; //得到长度(正确)
int length(int) ; //设置长度,返回前一个
//...
}
//返回n和v的长度中较大的一个
template
int padded_length(const Vector& v, int n)
{
int k = v.length(); //oops!不会编译、因为v是const引用。
return k>n?k:n;
}
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/409557/viewspace-891613/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/409557/viewspace-891613/