5

好吧,我有一个弱类型的类I.E.它可以存储定义为许多不同的类型:C++:重载操作符=

#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=来做这样的转换。

+0

IMO,“弱打字”通常是在C++中使用的一种痛苦,但也许你应该考虑boost :: any和boost :: variant,因为更好的轮子已经被发明出来。 – UncleBens 2010-01-15 23:05:10

+0

这看起来很像C语言union的定义。它也可以通过基于对象的类型执行测试来抵御OOP。 – 2010-01-16 00:57:31

回答

12

超载operator=更改将类别对象分配给时的行为。

如果您想要提供隐式转换为其他类型,则需要提供转换运算符,例如,

operator double() const 
{ 
    if (!isNumber) 
     throw something(); 
    return numVal; 
} 
+0

而且可以用派生类型如std :: string吗? – zmbush 2010-01-15 22:48:25

+0

是的,'operator std :: string()'是一个合法的转换运算符。 – 2010-01-15 22:55:54

+0

谢谢,它像一个魅力工作! – zmbush 2010-01-15 23:00:08

2

对于工作,你需要实现从你的对象转换操作符的东西,可以转换成一个双

7

你真正想要的转换操作符是什么。

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

这就是说,你可能会喜欢boost::variant

-1

要使一个类可以赋值给double,operator =必须以不同的方式定义。

double operator=(myclass&)是错误的。

什么工作,是一个朋友操作员=你的班级以外,它接受双和我的班&。

+1

你建议不能工作。赋值运算符必须是非静态成员函数,然后不能作为免费的朋友实现。 – 2010-01-15 22:52:45

2

返回值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=()(好吧,在技术上不存在双::运算符=()因为它是一种基本类型,而不是一个班级......只是在这里与我一起工作)。

一个有趣的提示是,该函数的行为与其他函数相同,因为返回值(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对象分配给基本类型时,您确实想要查看转换运算符

+0

谢谢你的解释,使用为我工作的转换操作符。 – zmbush 2010-01-16 00:38:33