所以,我前几天参加了考试,其中一个问题与此类似:
我们有一个叫做Square
变量的类int side
.我们怎样才能cout << static_cast<int>(aSquare) <<endl;
打印出a方形区域?
这甚至可能吗?
In *_*ico 23
有可能做到这一点,但不是通过重载static_cast<>()
.您可以通过重载类型转换运算符来实现:
class Square
{
public:
Square(int side) : side(side) {}
operator int() const { return side * side; } // overloaded typecast operator
private:
int side;
};
// ...
// Compiler calls Square::operator int() to convert aSquare into an int
cout << static_cast<int>(aSquare) <<endl;
Run Code Online (Sandbox Code Playgroud)
请注意,过度使用类型转换操作符往往会带来更多弊大于利.他们可以进行大量无意义的隐式转换操作.当您阅读下面的这段代码片段时,您是否认为"a将会获得s的区域"?
Square aSquare;
int a = aSquare; // What the heck does this do?
Run Code Online (Sandbox Code Playgroud)
我当然不会.这使得更有意义并且更具可读性:
Square aSquare;
int a = aSquare.GetArea();
Run Code Online (Sandbox Code Playgroud)
更何况,通常你希望能够访问有关的其他信息Square
,如GetSide()
或GetApothem()
或GetPerimeter()
或什么的.operator int()
显然只能返回一个int
,并且你不能将多个operator int()
s作为一个类的成员.
这是另一种情况,其中operator int()
编译的代码仍无任何意义:
Square s;
if(s > 42) {} // Huh?!
Run Code Online (Sandbox Code Playgroud)
a Square
大于42 是什么意思?这是无稽之谈,但是operator int()
上面的代码将编译为Shape
现在可以转换为int
可以int
与具有值的另一个进行比较的代码4
.
所以不要写那样的类型转换操作符.事实上,如果你超载了类型转换操作符,你可能需要三思而后行.实际上只有少数情况下,在现代C++中重载类型转换操作符是有用的(例如安全的bool习语).
您可以重载强制转换运算符:
struct square {
operator int() const {
return (side * side);
}
int side;
};
Run Code Online (Sandbox Code Playgroud)
唯一的问题是它会被隐式使用,并且在这里转换没有多大意义。您也无法区分不同类型的强制转换(static_cast、c-style 等)
这是做事的首选方式:
struct square {
int get_area() const {
return (side * side);
}
int side;
}
Run Code Online (Sandbox Code Playgroud)
如果必须使用强制转换,请使用 C++11 功能并将其标记为explicit
。这可以防止隐式转换错误。