Перегрузка static_cast? - PullRequest
       2

Перегрузка static_cast?

11 голосов
/ 10 декабря 2011

Итак, на днях у меня был экзамен, и один из вопросов был чем-то очень похожим на это:

У нас есть класс с именем Square, который содержит переменную int side.Как мы можем сделать так, чтобы cout << static_cast<int>(aSquare) <<endl; распечатывал площадь aSquare?

Это вообще возможно?

Ответы [ 3 ]

22 голосов
/ 10 декабря 2011

Это можно сделать, но не через перегрузку static_cast<>(). Вы делаете это, перегружая оператор typecast:

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() s в качестве членов класса.

Вот еще одна ситуация, когда operator int() создает код, который компилируется, но не имеет никакого смысла:

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

Что значит для Square быть больше 42? Это нонсенс, но с operator int() приведенный выше код будет компилироваться, так как Shape теперь можно преобразовать в int, который можно сравнить с другим int со значением 4.

Так что не пишите операторы Typecast. На самом деле, если вы перегружаете операторов typecast, вы можете дважды подумать о том, что вы делаете. На самом деле есть только несколько случаев, когда перегрузка оператора typecast полезна в современном C ++ (например, идиома безопасной bool ).

4 голосов
/ 10 декабря 2011

Вы можете перегрузить оператор приведения:

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. Это предотвращает неявные ошибки приведения.

1 голос
/ 10 декабря 2011

Вы можете указать оператор преобразования для класса Square:

class Square 
{
public:
    operator int()
    {
        return side * side;
    }
private:
    int side;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...