2012-05-29 31 views
7

Dòng A b (3) tạo ra sự mơ hồ vì nó có thể gọi bất kỳ một trong hai nhà xây dựng có thể có. Hoặc là đối số tham số duy nhất parametrized constructor hoặc đối số parametrized hai đối số với đối số mặc định. Tôi giải quyết điều này như thế nào?Làm thế nào để xử lý sự mơ hồ giữa constructor mặc định và constructor quá tải?

#include<iostream> 
using namespace std; 
class A 
{ 
    public: 
    int a,b; 
    A() 
    { 
     a=5; 
     b=6; 
    } 
    A(int a1) 
    { 
     a=a1; 
     b=54; 
    } 
    A(int a1,int b2=8) 
    { 
     a=a1; 
     b=b2; 
    } 
    void show() 
    { 
     cout<<"a="<<a<<" b="<<b<<endl; 
    } 
};  
int main() 
{ 
    A a(3); // I want A(int a1,int b2=8) to get executed 
    A b(3); // I want A(int a1) to get executed 
    a.show(); 
    b.show(); 
    return 0; 
} 
+0

Tránh những thứ như vậy để bắt đầu, bạn có hai lệnh gọi hàm tạo giống hệt nhau nhưng tạo ra các đối tượng khác nhau. –

+0

Trong một, bạn chỉ định 'b' 54 nếu không có đối số, và mặt khác, bạn chỉ định nó là 8 trong cùng hoàn cảnh. Có chuyện gì vậy? Tôi nghĩ đây là trường hợp của vấn đề XY. Nếu có một số lý do bạn muốn hành vi này, có một vấn đề cấp cao hơn. – chris

+0

là không có cách nào để giải quyết sự mơ hồ này để nó gọi constructor chúng ta muốn nó? – Ashwyn

Trả lời

5

Thứ nhất, câu trả lời này:

Khi bạn viết A a(4), bạn có muốn a.b. là:

Lựa chọn a)

class A 
{ 
    public: 
    int a,b; 
    A() 
    { 
     a=5; 
     b=6; 
    } 
    A(int a1,int b2 = 54) 
    { 
     a=a1; 
     b=b2; 
    } 
};  

Lựa chọn b)

class A 
{ 
    public: 
    int a,b; 
    A() 
    { 
     a=5; 
     b=6; 
    } 
    A(int a1,int b2 = 8) 
    { 
     a=a1; 
     b=b2; 
    } 
};  

Lỗi này là có lý do. Nếu bạn không biết những gì bạn muốn từ mã, làm thế nào bạn có thể mong đợi trình biên dịch?

EDIT: Sau khi chỉnh sửa - không thể. Không phải với mã chính xác đó.

+0

Đây là giải pháp thực sự duy nhất cho câu hỏi này. Logic đằng sau điều này là rất thiếu sót. Có hai hành vi khác nhau xuất phát từ cùng một mã. – chris

1

những gì bạn yêu cầu từ trình biên dịch có sự mơ hồ.

A(int a1) 
{ 
    a=a1; 
    b=54; 
} 

A(int a1,int b2=8) 
{ 
    a=a1; 
    b=b2; 
} 

đều giống nhau khi lớp học của bạn được tạo ra bởi chỉ có một tham số. ghi lại mong đợi của bạn từ các lớp học trong ngôn ngữ tiếng Anh cho chính mình đầu tiên. sau đó, chuyển nó sang mã C++. Ví dụ: "Nếu lớp A của tôi được tạo chỉ với một tham số, thay vì biến biến của tôi bằng tham số đó và để biến b của tôi là 54. Nếu nó được tạo bởi hai tham số, hãy cho biến thứ nhất thành một tham số và biến thứ hai b" và mã của bạn cho biểu thức này là:

A(int a1,int b2=54) 
{ 
    a=a1; 
    b=b2; 
} 
0

Trong ví dụ của bạn, không có cách nào để trình biên dịch cho biết bạn có nghĩa là hàm tạo thứ hai hoặc thứ ba khi nó được gọi với chỉ một đối số duy nhất.

Thông thường nếu bạn cần phải thêm một hàm tạo mới với các đối số mặc định bổ sung, bạn sẽ làm cho các giá trị mặc định dẫn đến hành vi tương tự như hàm khởi tạo trước đó và loại bỏ phiên bản cũ hơn, ví dụ: trong trường hợp này, mặc định cho b2 sẽ là 54. Ngoài ra, không cung cấp cho hàm tạo mới một đối số mặc định và chỉ yêu cầu người gọi chuyển nó một cách rõ ràng.

Tôi giả sử một tùy chọn khác là có nhiều lớp dẫn xuất với các hàm tạo mặc định chuyển các đối số khác nhau cho hàm tạo lớp cơ sở.

class A 
{ 
public: 
    int a, b; 
    A() { a = 5; b = 6; } 
    A(int a1) { a = a1; b = 54; } 
    A(int a1, int b1) { a = a1; b = b1; } 
    ... 
}; 

class B: public A 
{ 
public: 
    B(int a1): A(a1, 8) { } 
}; 

Mã muốn A: b khởi tạo bằng 8 thay vì 54 tạo B thay thế. Đó không phải là một lựa chọn tốt trong nhiều tình huống.

1

Remove A(int a1) chức năng và thay vì A b(3) gọi A b(3, 54)

0

tôi loại bỏ các mặc định = 8 trong constructor và nó sửa chữa nó. Bạn có thể chỉ định 54 trong việc thực thi hàm tạo, nhưng không phải là một tham số.Nếu không, nó sẽ gây nhầm lẫn nó với hàm tạo khác mà không có tham số = 8 đó.

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