重载static_cast?

时间:2011-12-10 17:52:50

标签: c++ casting

所以,我前几天参加了考试,其中一个问题与此非常相似:

我们有一个名为Square的类,它包含变量int side。我们怎样才能使cout << static_cast<int>(aSquare) <<endl;打印出方形区域?

这甚至可能吗?

3 个答案:

答案 0 :(得分:22)

可以实现这项工作,但不能通过重载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;

请注意,重载的类型转换操作符通常往往弊大于利。他们可以进行大量无意义的隐式转换操作。当您阅读下面的代码片段时,您是否认为“a将会获得s区域”?

Square aSquare;
int a = aSquare; // What the heck does this do?

我当然不会。这样做更有意义,更具可读性:

Square aSquare;
int a = aSquare.GetArea();

更不用说通常您希望能够访问有关Square的其他信息,例如GetSide()GetApothem()GetPerimeter()或其他任何信息。 operator int()显然只能返回一个int,并且您不能将多个operator int()作为一个类的成员。

这是另一种情况,operator int()使得编译的代码无论如何都没有意义:

Square s;
if(s > 42) {} // Huh?!

Square大于42是什么意思?这是无稽之谈,但使用operator int()上面的代码将编译为Shape现在可以转换为int,可以与另一个int进行比较,其值为4 }。

所以不要写那样的类型转换操作符。事实上,如果你超载了类型转换操作符,你可能需要三思而后行。实际上只有少数情况下,在现代C ++中重载typecast运算符很有用(例如the safe bool idiom)。

答案 1 :(得分:4)

您可以重载强制转换运算符:

struct square {
  operator int() const {
    return (side * side);
  }
  int side;
};

唯一的问题是它将被隐式使用,并且在这里投射没有多大意义。你也无法区分不同类型的演员表(static_cast,c-style等)

这是做事的首选方式:

struct square {
  int get_area() const {
    return (side * side);
  }
  int side;
}

如果必须使用强制转换,请使用C ++ 11功能并将其标记为explicit。这可以防止隐式转换错误。

答案 2 :(得分:1)

您可以为Square类提供转换运算符:

class Square 
{
public:
    operator int()
    {
        return side * side;
    }
private:
    int side;
};