5

Okay, quindi ho una classe che ha una "digitazione debole" I.E. è in grado di memorizzare molti tipi differenti definiti come:C++: Operatore di overloading =

#include <string> 

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

     bool isNumber; 
     double numVal; 

     bool isBoolean; 
     bool boolVal; 

     double operator= (const myObject &); 
}; 

vorrei sovraccaricare l'operatore di assegnazione in questo modo:

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

In modo che io possa fare questo:

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

Ma quando Lo faccio, ottengo:

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

Al compito.

Ho anche provato:

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

Al che ottengo:

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

C'è qualcosa che mi manca? o semplicemente non è possibile fare una conversione del genere sovraccaricando operator=.

+0

IMO, "tipizzazione debole" è generalmente un problema con cui lavorare in C++, ma forse dovresti dare un'occhiata a boost :: any e boost :: variant perché le ruote migliori sono già state inventate. – UncleBens

+0

Sembra molto simile alla definizione di un 'unione' in linguaggio C. Funziona anche contro OOP eseguendo un test basato sul tipo di un oggetto. –

risposta

12

Il sovraccarico operator= modifica il comportamento durante l'assegnazione di oggetti a del tipo di classe.

Se si desidera fornire la conversione implicita ad altri tipi, è necessario fornire un operatore di conversione, ad es.

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

E può anche essere usato con tipi derivati ​​come std :: string? – zmbush

+0

Sì, 'operator std :: string()' è un operatore di conversione legale. –

+0

Grazie, ha funzionato come un fascino! – zmbush

2

per quella di lavorare, è necessario implementare un operatore di conversione dal tuo oggetto al qualcosa che può essere convertito in un letto

7

cosa si vuole veramente sono operatori di conversione.

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

Detto questo, si sarebbe probabilmente piace boost::variant.

-1

Per rendere una classe assegnabile a un doppio, l'operatore = deve essere definito in modo diverso.

double operator=(myclass&) è errato.

Che cosa potrebbe funzionare, è un operatore amico = al di fuori della classe, che accetta doppio e myclass &.

+1

Ciò che suggerisci non può funzionare. Gli operatori di assegnazione devono essere funzioni membro non statiche, quindi non possono essere implementati come amici gratuiti. –

2

Il valore di ritorno di operator=() non può essere utilizzato come si è tentato di dimostrare. Se si pensa all'operatore sovraccarico come una funzione a sé stante, può avere più senso.

Ad esempio:

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

Il motivo number = obj; non funziona è perché avete definito myObject::operator=(), mentre number sarebbe utilizzando double::operator=() (ok, tecnicamente non c'è doppia :: operator =() poiché è un tipo fondamentale e non una classe ... lavora solo con me qui).

Una nota interessante è che questa funzione si comporta come qualsiasi altra funzione in quanto il valore di ritorno (return right.numval;) viene ignorato quando non viene utilizzato. Tuttavia, il valore di ritorno può essere ceduto o utilizzato come il valore di ritorno di ogni altra funzione, quindi se si voleva davvero si potrebbe fare qualcosa di simile:

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) 
} 

Questo è solo così utile. Come altri hanno già accennato, si vuole veramente esaminare gli operatori di conversione quando si tenta di assegnare gli oggetti myObject ai tipi fondamentali.

+0

Grazie per la spiegazione, l'utilizzo degli operatori di conversione ha funzionato per me. – zmbush