Хорошо, таким образом, у меня есть класс, который имеет 'слабый контроль типов', Т.Е. он может сохранить много различных типов, определенных как:
#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=
.
Overload operator=
изменяет поведение при назначении объектов к объектам Вашего типа класса.
Если Вы хотите обеспечить неявное приведение к другим типам, Вам необходимо предоставить оператор приведения, например,
operator double() const
{
if (!isNumber)
throw something();
return numVal;
}
Что вы действительно хотите, являются операторами преобразования.
operator double() const { return numVal; }
operator int() const { ...
Это сказано, что вы, вероятно, понравились Boost :: Variant .
Для этого необходимо работать, вам необходимо реализовать оператор преобразования от вашего объекта к чему-то, что можно преобразовать в двойную
Чтобы сделать класс, назначенный на двойной, оператор = должен быть определен по-разному.
Двойной оператор = (MyClass &)
неверно.
Что бы работать, является оператором друга = за пределами вашего класса, который принимает двойной и MyClass &.
Возвращаемое значение 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
фундаментальным типам.