完全掌握C++编程中构造函数使用的超级学习教程

2020-01-06 14:26:49王冬梅


class Box {
public:
  Box(int width, int length, int height) 
    : m_width(width), m_length(length), m_height(height) // member init list
  {}
  int Volume() {return m_width * m_length * m_height; }
private:
  int m_width;
  int m_length;
  int m_height;

};

创建 Box 对象:


Box b(42, 21, 12);
cout << "The volume is " << b.Volume();

显式构造函数
如果类具有带一个参数的构造函数,或是如果除了一个参数之外的所有参数都具有默认值,则参数类型可以隐式转换为类类型。例如,如果 Box 类具有一个类似于下面这样的构造函数:


Box(int size): m_width(size), m_length(size), m_height(size){}

可以初始化 Box,如下所示:


Box b = 42;

或将一个 int 传递给采用 Box 的函数:


class ShippingOrder
{
public:
  ShippingOrder(Box b, double postage) : m_box(b), m_postage(postage){}

private:
  Box m_box;
  double m_postage;
}
//elsewhere...
  ShippingOrder so(42, 10.8);


这类转换可能在某些情况下很有用,但更常见的是,它们可能会导致代码中发生细微但严重的错误。作为一般规则,应对构造函数使用 explicit 关键字(和用户定义的运算符)以防止出现这种隐式类型转换:


explicit Box(int size): m_width(size), m_length(size), m_height(size){}

构造函数是显式函数时,此行会导致编译器错误:ShippingOrder so(42, 10.8);。
默认构造函数
默认构造函数没有参数;它们遵循略有不同的规则:
默认构造函数是一个特殊成员函数;如果没有在类中声明构造函数,则编译器会提供默认构造函数:


class Box {
  Box(int width, int length, int height) 
    : m_width(width), m_length(length), m_height(height){}
};

int main(){

  Box box1{}; // call compiler-generated default ctor
  Box box2;  // call compiler-generated default ctor
}

当你调用默认构造函数并尝试使用括号时,系统将发出警告:


class myclass{};
int main(){
myclass mc();   // warning C4930: prototyped function not called (was a variable definition intended?)
}

这是“最棘手的解析”问题的示例。这种示例表达式既可以解释为函数的声明,也可以解释为对默认构造函数的调用,而且 C++ 分析器更偏向于声明,因此表达式会被视为函数声明。