`
mooncui
  • 浏览: 72532 次
社区版块
存档分类
最新评论

《C++沉思录》笔记---类设计者核查表

    博客分类:
  • C++
阅读更多

类设计者的核查表
1. 类需要构造函数么?
2. 数据是否需要保持私有的?
方案一
public:
 int length;
 
方案二
public:
 const int& length;//在构造函数中length = true_length;这样由于是const变量,只能读,不能修改。
private:
 int true_length;
 
方案三
public:
 int length() const;//

3. 是否需要一个无参的构造函数?
如果没有无参的构造函数,那么
Point p;
Point pa[100];
这样的定义都是错误的。
4. 是不是每个构造函数初始化所有的数据成员?
构造函数的用途就是用一种明确定义的状态来设置对象,而这个对象是由对象的数据成员反映的。
因此每个构造函数都要负责为所有数据成员设置明确定义的值。(特殊的例外)
5. 是否需要析构函数?
如果有内存是在类中new出来,但一直也没有释放的,需要在析构函数中释放掉。
6. 是否需要虚析构函数?
如果一个基类B被派生了一个子类D,无论B是否有虚函数
B* d = new D();
delete d;  //B都需要虚析构函数,否则这里会调用错误的析构函数

7. 是否需要复制构造函数?
因为data的内存是另外动态分配的。所以应该需要析构函数来释放data空间
class String{
public:
 String();
 String(const char* s);
private
 char* data
}
因为data的内存是另外动态分配的。所以应该需要析构函数来释放data的空间。
同样也需要复制构造函数,因为如果没有的话,如果复制对象
    String b = a
就是仅复制data的地址,b.data和a.data指象同一个内存,在两个对象销毁时,这个内存会被释放两次。
如果不希望用户能够复制类的对象,就声明复制构造函数(可能还有赋值操作符)为私有的
class Thing{
private
 Thing(const Thing&);
 Thing& operator=(const Thing&);
}

8. 需要一个赋值操作符么?
是否需要的理由和复制构造函数是一样的。
Thing& operator=(const Thing&);
由return *this;结束以保证与内建的复制操作符一致。
写这个函数的时候还要注意赋值给自身的情况
String& String::operator=(const String& s)
{
 delete[] data;  //如果是赋值给自身的情况,s.data也给delete了,所有后面都是错了
 data = new char[strlen(s.data)+1];
 strcpy(data,s.data);
 return *this;
}
所以最好:
String& String::operator=(const String& s)
{
 if( &s != this){
  delete[] data; 
  data = new char[strlen(s.data)+1];
  strcpy(data,s.data);
  return *this;
 }
}
或:
String& String::operator=(const String& s)
{
 char* newdata = new char[strlen(s.data)+1];
 strcpy(newdata,s.data);
 delete[] data; 
 data = newdata;
 return *this;
}

9. 需要定义关系操作符么?
如果类逻辑上支持相等操作,那么提供operate==,operate!=,就可能有好处
如果类的值有某种排序关系,那就考虑其他 < > 等操作符

10. 删除数据用delete[]了么?
删除数组是用delete[]是个好习惯。这种用法是为了与C兼容,实现时会有个地方记录数组的长度

11. 记得在复制构造函数和赋值操作符的参数类型中加const了么?
X::X(const X&)
X::operator=(const X&)

12. 如果函数有引用参数,它们应该是const引用么?
Complex operator+(const Complex& x,const Complex& y);

13. 记得适当地声明成员函数为const了么?
如果一个成员函数不会修改其对象(一般get方法),可以声明它为const,这样它才可以应用于const对象。
例如:
int padded_length(const Vector<t></t>& v,int n)
{
 int k = v.length(); //由于v是const的,所以length()函数也需要定义成const,否则编译不通过。
 return k>n?k:n;
}

分享到:
评论
1 楼 BIGN 2007-09-18  
<<沉思 3>>共想可下载

相关推荐

Global site tag (gtag.js) - Google Analytics