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++ 分析器更偏向于声明,因此表达式会被视为函数声明。










