2016-06-06 24 views
24

Tại sao nó hoạt động để trả lại int trong phương thức B minus nếu phương pháp được cho là trả về một đối tượng thuộc loại B?Tại sao nó hoạt động để trả về một int trong một phương thức mà trả về một đối tượng?

#include <iostream> 

class B 
{ 
public: 
    int a; 
public: 
    B(int i=0) 
    { 
     a=i; 
    } 
    B minus() 
    { 
     return (1-a); 
    } 
}; 

int main() 
{ 
    B x(18); 
    x = x.minus(); 
    std::cout << x.a << '\n'; 
    return 0; 
} 
+16

Bạn đã không đánh dấu constructor 'explicit' của bạn. – user2357112

+3

Nhìn vào hàm tạo 'B' của bạn. 'B' được xây dựng như thế nào? – PaulMcKenzie

+0

Tôi giả sử vì hàm tạo có int, nó ngầm xây dựng từ int, là tốt. –

Trả lời

53

Một hàm tạo với một đối số được coi là một hàm tạo chuyển đổi . Khi một đối số của kiểu X là cần thiết, và một kiểu Y được cho thay vào đó, trình biên dịch sẽ tìm kiếm một hàm tạo chuyển đổi (hoặc một toán tử chuyển đổi kiểu) từ Y thành X. Trong trường hợp này, nó tìm thấy một, sử dụng hàm tạo B(int) của bạn. Về bản chất, return (1-a); của bạn được đổi thành return B(1-a);.

Như đã đề cập trong một số câu trả lời khác (cũng chính xác), nếu bạn không muốn hàm tạo được coi là một hàm tạo chuyển đổi, bạn nên bắt đầu từ khóa với từ khóa explicit.

13

Điều này xảy ra vì hàm tạo đối số đơn có thể được sử dụng như một diễn viên ngầm từ kiểu đối số sang loại đối tượng.

Trong trường hợp của bạn, bạn có một hàm tạo chấp nhận đối số kiểu int, vì vậy hàm tạo này có thể được sử dụng để chuyển đổi int thành B.

Để ngăn các hàm tạo này được sử dụng trong chuyển đổi, bạn nên đánh dấu hàm tạo explicit - và thực hành tốt cho tất cả các hàm tạo đối số đơn, vì trong thực tế, các chuyển đổi tiềm ẩn thường không mong muốn hơn mong muốn.

27

Dòng

return (1-a); 

gọi constructor chuyển đổi ngầm

B(int i=0) 
{ 
    a=i; 
} 

Vì vậy, nó giống như viết

return B(1-a); 

Lưu ý rằng các nhà xây dựng bản sao vẫn được tạo ra, trừ khi bạn delete.


Nếu bạn muốn tránh điều đó, hãy viết

explicit B(int i=0) 
// ^^^^^^^^ 
    { 
     a=i; 
    } 

này sẽ thực sự buộc một người sử dụng để viết

return B(1-a); 
Các vấn đề liên quan