int main() {
int theInt = 5;
/**
* Constructor "Example(int val)" in effect at the statement below.
* Same as "Example exObject(theInt);" or "Example exObject = Example(theInt);"
*/
Example exObject = theInt; // 1
Example ctr(5);
/**
* "operator unsigned int()" in effect at the statement below.
* What gets assigned is the value returned by "operator unsigned int()".
*/
int theInt1 = ctr; // 2
return 0;
}
在语句 1Example(int val)
中调用构造函数。将其声明为explicit Example(int val)
,您将得到一个编译时错误,即不允许此构造函数进行隐式转换。
如果分配的值属于它们各自的参数类型,则所有单参数构造函数都会被隐式调用。在单参数构造函数之前使用explicit
关键字会禁用隐式构造函数调用,从而禁用隐式转换。
如果构造函数被声明为显式 ie explicit Example(int val)
,那么每个语句都会发生以下情况。
Example exObject(theInt); // Compile time error.
Example exObject = theInt; // Compile time error.
Example exObject(Example(theInt)); // Okay!
Example exObject = Example(theInt); // Okay!
另请注意,在隐式构造函数调用和隐式转换的情况下,分配的值是一个右值,即使用左值(theInt)隐式创建的未命名对象,它告诉我们在隐式转换的情况下编译器转换
Example exObject = theInt;
至
Example exObject = Example(theInt);
因此(在 C++11 中)不要指望调用左值构造函数,因为您正在使用左值,即指定值theInt
进行赋值。调用的是右值构造函数,因为分配的值实际上是使用左值创建的未命名对象。但是,如果您同时具有构造函数的左值和右值版本,则这适用。
在语句 2operator unsigned int()
处被调用。只需将其视为具有奇怪名称的普通函数调用,并且在发生隐式转换时可以自动调用它。该函数返回的值是表达式中分配的值。而且由于在您的实现中,返回的值是一个 int ,它被正确分配给int theInt1
.
确切地说,operator unsigned int()
重载()
运算符是强制转换运算符。int
在您的情况下,每当将Example
类的对象分配给int
隐式类型转换 from Example
toint
并因此operator unsigned int()
被调用时,它就会重载。所以,
int theInt1 = ctr;
相当于
int theInt1 = (int)ctr;