一个典型的基于对象的类为complex, 类的实现不需要指针且只由c++的内置类型组成,
对于这种类的设计要点注意事项就拿complex的实现作为例子, 部分代码如下:

  4 class complex
  5 {
  6 public:
  7     complex (double r=0, double i=0) : re(r), im(i) {}
  8     //complex (){};
  9     complex & operator += (const complex &);
 10     double real () const { return re;}
 11     double imag () const { return im;}
 12  
 13 private:
 14     double re, im;
 15  
 16     friend complex& __doapl(complex *, const complex &);
 17 };

不要设计冗余的构造函数

其中构造函数complex(){}虽然和第七行的构造函数会生成不符号名(函数入参也是构成签名),
分别解析输出的二进制文件,找到两者的符号分别是:

_ZN7complexC2Edd    // complex(double, double)
_ZN7complexC2Ev     // complex()

因此,当程序中未使用此构造函数的时候不会因为命名冲突而报错, 而当代码中做如下定义:

complex a;

会产生歧义, 编译器不知道使用哪个构造函数而报错. 因此, 类设计的时候就不要声明,
保留覆盖范围更广的complex(double, double)构造函数即可.

那么有一个疑问, 为了保证类后续的维护者不会新增这个无效的complex()构造函数, 
可不可以把它直接放到private里面去呢? 不可以的, 用gcc试验的结果是, 编译器会先
遍历匹配函数, 找到了之后再判断函数的可见性, 公有的还是私有的, 所以放private并没啥用

操作符的用途决定操作符重载函数的返回形式

operator <<为例, 实际上用途就两种, 或者执行完<<之后还能作为左值, 或者不作为左值
基于以下两点考虑, 输出操作符重载函数应该作为类的非成员函数, 声明形式如下:

ostream &operator << (ostream &os, const complex &x);

  1. 兼容作为左值, 可以继续拼接标准输出动作, 需要把引用作为返回值.

  2. 按照c++标准输出的习惯, ostream都是作为第一个参数即:cout<<a;


Ender
599 声望17 粉丝