2012-09-09 36 views
6

Hãy có mã này:C++: dàn diễn viên hành vs điều hành assign vs ưu tiên constructor chuyển đổi

Test1 t1; 
Test2 t2; 
t1 = t2; 

Tôi tin rằng có ba cách làm thế nào để thực hiện t1 = t2

  • đến (hoặc nhiều hơn?) toán tử gán quá tải trong Test1
  • cho nhà điều hành dàn diễn viên loại quá tải trong Test2
  • để tạo Test1(const Test2&) chuyển đổi constructor

Theo thử nghiệm GCC của tôi, đây là ưu tiên hàng đầu của những gì được sử dụng:

  1. hành assign
  2. chuyển đổi nhà xây dựng và điều hành loại cast (mơ hồ)
  3. const constructor chuyển đổi và toán tử cast kiểu const (mơ hồ)

Hãy giúp tôi hiểu lý do ưu tiên này.

tôi sử dụng mã này để thử nghiệm (bỏ ghi chú một số dòng để thử)

struct Test2; 
struct Test1 { 
    Test1() { } 
    Test1(const Test2& t) { puts("const constructor wins"); } 
// Test1(Test2& t) { puts("constructor wins"); } 
// Test1& operator=(Test2& t) { puts("assign wins"); } 
}; 

struct Test2 { 
    Test2() { } 
// operator Test1() const { puts("const cast wins"); return Test1(); } 
// operator Test1() { puts("cast wins"); return Test1(); } 
}; 


int main() { 
    Test1 t1; 
    Test2 t2; 
    t1 = t2; 
    return 0; 
} 
+0

'Test1 :: Test1 (const Test2 &)' không phải là "hàm tạo bản sao", nó là "hàm tạo chuyển đổi". – aschepler

+0

Bài đăng này giải thích chính xác lý do tại sao toán tử chuyển đổi có ưu tiên cao hơn: http://stackoverflow.com/questions/1384007/conversion-constructor-vs-conversion-operator-precedence –

Trả lời

13

Tuyên bố t1 = t2; tương đương với:

t1.operator=(t2); 

Bây giờ các quy tắc thông thường của độ phân giải quá tải áp dụng. Nếu có một trận đấu trực tiếp, đó là trận đấu được chọn. Nếu không, thì chuyển đổi ngầm định được xem xét để sử dụng với toán tử gán bản sao (được tạo tự động, "được xác định ngầm").

Có hai chuyển đổi tiềm ẩn, do người dùng xác định. Tất cả các chuyển đổi người dùng định nghĩa đếm bằng nhau, và nếu cả hai được xác định, sự quá tải là mơ hồ:

  • Chuyển đổi t2 đến một Test1 qua các nhà xây dựng Test1::Test1(Test2 const &) chuyển đổi.

  • Chuyển đổi t2 thành Test1 qua số Test2::operator Test1() const nhà điều hành truyền.

+0

Trong ví dụ ideone thứ hai của @ Luchian, hàm chuyển đổi giành chiến thắng vì nó liên kết một 'Test2 &' với 't2', không phải là' const Test2 & '. Tôi nghĩ rằng http://ideone.com/U38vK được cho là không rõ ràng, nhưng có vẻ như g ++ thích constructor. – aschepler

+2

Aha. g ++ DOES gọi chúng là mơ hồ nếu bạn yêu cầu '-pedantic'. Mặc định nghịch ngợm g ++. – aschepler

+0

@KerrekSB: Nếu toán tử cast không phải là hằng số, nó sẽ đánh bại hàm tạo chuyển đổi và không có sự mơ hồ. http://liveworkspace.org/code/7795254ae49b4d6350f0ede57615e4c6 –

Các vấn đề liên quan