C ++: оператор перегрузки = - PullRequest
5 голосов
/ 16 января 2010

Хорошо, у меня есть класс со слабой типизацией I.E. он может хранить много разных типов, определенных как:

#include <string>

class myObject{
   public:
      bool isString;
      std::string strVal;

      bool isNumber;
      double numVal;

      bool isBoolean;
      bool boolVal;

      double operator= (const myObject &);
};

Я бы хотел перегрузить оператор присваивания следующим образом:

double myObject::operator= (const myObject &right){
   if(right.isNumber){
      return right.numVal;
   }else{
      // Arbitrary Throw.
      throw 5;
   }
}

Так что я могу сделать это:

int main(){
   myObject obj;
   obj.isNumber = true;
   obj.numVal = 17.5;
   //This is what I would like to do
   double number = obj;
}

Но когда я это делаю, я получаю:

error: cannot convert ‘myObject’ to ‘double’ in initialization 

При назначении.

Я также пробовал:

int main(){
   myObject obj;
   obj.isNumber = true;
   obj.numVal = 17.5;
   //This is what I would like to do
   double number;
   number = obj;
}

На что я получаю:

error: cannot convert ‘myObject’ to ‘double’ in assignment

Что-то мне не хватает? или просто невозможно выполнить такое преобразование, перегрузив operator=.

Ответы [ 5 ]

12 голосов
/ 16 января 2010

Перегрузка operator= изменяет поведение при назначении объектов вашего типа класса.

Если вы хотите обеспечить неявное преобразование в другие типы, вам необходимо указать оператор преобразования, например,

operator double() const
{
    if (!isNumber)
        throw something();
    return numVal;
}
7 голосов
/ 16 января 2010

Что вы действительно хотите, так это операторы преобразования.

operator double() const { return numVal; }
operator int() const { ...

Тем не менее, вы, вероятно, хотели бы boost :: variable .

2 голосов
/ 16 января 2010

Возвращаемое значение operator=() не может быть использовано, как вы пытались продемонстрировать. Если вы думаете о перегруженном операторе как о отдельной функции, это может иметь больше смысла.

Например:

int main() {
  myObject obj, obj2;
  obj.isNumber = true;
  obj.numVal = 17.5;
  obj2.operator=(obj); // equivalent to obj2 = obj
}

Причина number = obj; не работает в том, что вы определили myObject::operator=(), тогда как number будет использовать double::operator=() (хорошо, технически нет double :: operator = () поскольку это фундаментальный тип, а не класс ... просто работайте со мной здесь).

Интересно отметить, что эта функция ведет себя как любая другая функция в том, что возвращаемое значение (return right.numval;) игнорируется, когда оно не используется. Однако возвращаемое значение может быть назначено или использовано как возвращаемое значение любой другой функции, поэтому, если вы действительно хотите, вы можете сделать что-то вроде этого:

int main() {
  myObject obj, obj2;
  obj.isNumber = true;
  obj.numVal = 17.5;
  double number;
  // number = obj; still won't work.
  number = obj2 = obj; // equivalent to number = obj2.operator=(obj)
}

Это только так полезно. Как уже упоминалось, вы действительно хотите изучить операторы преобразования при попытке назначить myObject объекты фундаментальным типам.

2 голосов
/ 16 января 2010

, чтобы это работало, вам нужно реализовать оператор преобразования из вашего объекта во что-то, что может быть преобразовано в двойное

0 голосов
/ 16 января 2010

Чтобы сделать класс, присваиваемый типу double, оператор = должен быть определен по-другому.

double operator=(myclass&) неверно.

Что бы сработало, оператор друга = вне вашего класса, который принимает double и myclass &.

...