2010-03-19 37 views
11

Tôi đã luôn luôn là một cậu bé ngoan khi viết các lớp học của tôi, tiền tố tất cả các biến thành viên với m_:C++ Constructor danh sách khởi lạ

class Test { 
    int m_int1; 
    int m_int2; 
public: 
    Test(int int1, int int2) : m_int1(int1), m_int2(int2) {} 
}; 

int main() { 
    Test t(10, 20); // Just an example 
} 

Tuy nhiên, thời gian gần đây tôi quên để làm điều đó và kết thúc bằng văn bản:

class Test { 
    int int1; 
    int int2; 
public: 
    // Very questionable, but of course I meant to assign ::int1 to this->int1! 
    Test(int int1, int int2) : int1(int1), int2(int2) {} 
}; 

Tin hay không, mã được biên dịch không có lỗi/cảnh báo và các bài tập đã diễn ra chính xác! Đó là chỉ khi làm kiểm tra cuối cùng trước khi kiểm tra trong mã của tôi khi tôi nhận ra những gì tôi đã làm.

Câu hỏi của tôi là: tại sao mã của tôi biên dịch? Là một cái gì đó như vậy cho phép trong tiêu chuẩn C + +, hoặc là nó chỉ đơn giản là một trường hợp của trình biên dịch được thông minh? Trong trường hợp bạn đang tự hỏi, tôi đã sử dụng Visual Studio 2008

+4

Mang tên của bạn khó có thể coi là một "cậu bé tốt". Như bạn đã phát hiện ra, nó thường không cần thiết, và trong những dịp hiếm hoi mà nó xảy ra, chúng ta có tiền tố 'this->' này. – jalf

+0

Có lẽ một bản dupe, xem http://stackoverflow.com/questions/2227244/what-if-a-constructor-parameter-has-the-same-name-as-a-member-variable-in-c – Abhay

+2

@jalf : Mặt khác, một số loại chỉ báo thành viên var có thể làm cho mã đọc dễ dàng hơn (tôi sử dụng dấu _ khi nó không phá vỡ quy ước hiện tại). –

Trả lời

26

Có, nó hợp lệ. Các tên trong danh sách khởi tạo thành viên được tra cứu trong ngữ cảnh của lớp của hàm tạo để int1 tìm tên của biến thành viên.

Biểu thức khởi tạo được tra cứu trong ngữ cảnh của hàm tạo, vì vậy, int1 tìm tham số che dấu các biến thành viên.

+2

Chính xác, và đặt chính xác. Bravo! +1 –

+0

+1, cậu bé dũng cảm! xD –

0

Tôi tưởng tượng điều này hoạt động vì bạn đang sử dụng int1 trong danh sách khởi tạo và chỉ những thứ bạn có thể khởi tạo là các biến thành viên => đang được khởi tạo.

Cho dù tất cả các trình biên dịch C++ sẽ được tha thứ này là một vấn đề khác!

+0

IIRC g ++ cũng cho phép :-). – p4bl0

+11

Đây là tiêu chuẩn C++. –

+1

Cảm ơn bạn đã giải thích. Tất nhiên chỉ có các biến thành viên có thể xuất hiện bên ngoài dấu ngoặc đơn trong danh sách khởi tạo. Nhưng những gì bên trong dấu ngoặc đơn không hoàn toàn rõ ràng. Ví dụ, nếu chúng ta có: Test (int int1): int1 (int1 + 1), int2 (int1) {} bây giờ int1 trên ngoặc thứ hai có nghĩa là gì?Nó có nghĩa là :: int1 hay có nghĩa là this-> int1? – Andy

15

Điều bạn đã làm là chuẩn C++. Chỉ các biến thành viên hoặc các lớp cơ sở có thể được initliazed trong danh sách khởi tạo, do đó, biến bên ngoài dấu ngoặc đơn là rõ ràng. Trong ngoặc đơn, các quy tắc phạm vi điển hình được áp dụng và các thành viên bị lu mờ bởi các tên thông số.

+1

+1 Đây là câu trả lời duy nhất tuyên bố rằng đây là tiêu chuẩn C++ cũng như đưa ra lời giải thích. –

2

Đây là hành vi hoàn toàn bình thường. Như AAT đã chỉ ra đúng, không có sự mơ hồ. Các biến được khởi tạo bởi danh sách phải là thành viên của lớp. Đây là tiêu chuẩn và hoạt động trên tất cả các trình biên dịch tuân thủ.

Điều duy nhất cần nhớ khi sử dụng danh sách như thế này là một người không hiểu loại mã này có thể phải duy trì nó. Không có gì sai khi viết mã khởi tạo như thế này miễn là bạn biết bạn đang làm gì.

0

Điều bạn đã làm là bình thường. Loại triển khai này tránh bạn thậm chí sử dụng con trỏ 'this' (trong trường hợp này).

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