5

Được rồi vì vậy tôi có một lớp học có 'đánh máy yếu' I.E. nó có thể lưu trữ nhiều loại khác nhau định nghĩa là:C++: Toán tử quá tải =

#include <string> 

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

     bool isNumber; 
     double numVal; 

     bool isBoolean; 
     bool boolVal; 

     double operator= (const myObject &); 
}; 

Tôi muốn quá tải toán tử gán như thế này:

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

Vì vậy mà tôi có thể làm điều này:

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

Nhưng khi Tôi làm như vậy, tôi nhận được:

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

Khi chuyển nhượng.

Tôi cũng đã cố gắng:

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

Để mà tôi nhận được:

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

Có điều gì tôi đang thiếu? hoặc đơn giản là không thể thực hiện chuyển đổi như vậy bằng cách quá tải operator=.

+0

IMO, "gõ nhẹ" nói chung là một nỗi đau để làm việc với trong C + +, nhưng có lẽ bạn nên xem xét tăng :: bất kỳ và tăng :: biến thể bởi vì bánh xe tốt hơn đã được phát minh. – UncleBens

+0

Điều này trông rất giống với định nghĩa của một ngôn ngữ C 'union'. Nó cũng hoạt động với OOP bằng cách thực hiện một thử nghiệm dựa trên kiểu của một đối tượng. –

Trả lời

12

Quá tải operator= thay đổi hành vi khi gán các đối tượng đến đối tượng thuộc loại lớp học của bạn.

Nếu bạn muốn cung cấp chuyển đổi tiềm ẩn cho các loại khác, bạn cần cung cấp toán tử chuyển đổi, ví dụ:

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

Và điều đó cũng có thể được sử dụng với các loại có nguồn gốc như std :: string? – zmbush

+0

Có, 'toán tử std :: string()' là toán tử chuyển đổi hợp pháp. –

+0

Cảm ơn bạn, nó hoạt động như một sự quyến rũ! – zmbush

2

cho rằng để làm việc, bạn cần phải thực hiện một nhà điều hành chuyển đổi từ đối tượng của bạn để một cái gì đó có thể được chuyển đổi thành một đôi

7

gì bạn thực sự muốn là nhà khai thác chuyển đổi.

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

Điều đó nói rằng, bạn có thể thích boost::variant.

-1

Để làm cho lớp có thể được gán cho nhân đôi, toán tử = phải được xác định khác nhau.

double operator=(myclass&) là sai.

Điều gì sẽ hiệu quả, là nhà điều hành bạn bè = bên ngoài lớp học của bạn, chấp nhận gấp đôi và lớp học &.

+1

Những gì bạn đề xuất không thể hoạt động. Các toán tử gán phải là các hàm thành viên không tĩnh, sau đó không thể được thực hiện như những người bạn miễn phí. –

2

Không thể sử dụng giá trị trả lại của operator=() như bạn đã cố gắng chứng minh. Nếu bạn nghĩ toán tử quá tải như là một hàm trong quyền riêng của nó, nó có thể có ý nghĩa hơn.

Ví dụ:

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

Lý do number = obj; không hoạt động là bởi vì bạn đã xác định myObject::operator=(), trong khi number sẽ sử dụng double::operator=() (okay, về mặt kỹ thuật không có đôi :: operator =() vì đây là một loại cơ bản và không phải là một lớp ... chỉ làm việc với tôi ở đây).

Một lưu ý thú vị là chức năng này hoạt động giống như bất kỳ chức năng nào khác trong đó giá trị trả lại (return right.numval;) bị bỏ qua khi nó không được sử dụng. Tuy nhiên, giá trị trả về có thể được chỉ định hoặc sử dụng như giá trị trả về của bất kỳ hàm nào khác, vì vậy nếu bạn thực sự muốn bạn có thể làm điều gì đó như sau:

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

Điều này chỉ hữu ích. Như những người khác đã đề cập, bạn thực sự muốn xem xét các nhà điều hành chuyển đổi khi cố gắng chỉ định myObject đối tượng cho các loại cơ bản.

+0

Cảm ơn bạn đã giải thích, sử dụng toán tử chuyển đổi đã làm việc cho tôi. – zmbush