2011-10-26 28 views
7

Trong ví dụ sau, kích thước của mảng v có đảm bảo là 2 hoặc 3 không?Phạm vi của các thành viên trong lớp

static const int i = 3; 

class X { 

    char v[i]; 
    static const int i = 2; 
}; 

Từ tiêu chuẩn,

3.3.6/2 Một tên N được sử dụng trong một lớp S sẽ đề cập đến việc kê khai tương tự trong bối cảnh của nó và khi tái đánh giá trong phạm vi hoàn thành của S

Tôi nghĩ điều này có nghĩa là 'i' sẽ là 2 và điều đánh giá lại thực sự có ý nghĩa gì ở đây?

Trả lời

4

Các hành vi đúng là nó phải gây ra một lỗi vì đánh giá lại sẽ thay đổi ý nghĩa:

Ví dụ từ phần 3.3.6:

Phạm vi tiềm năng của một tuyên bố mà kéo dài tới hoặc quá khứ của định nghĩa lớp cũng mở rộng đến các vùng được định nghĩa bởi các định nghĩa thành viên của nó, ngay cả khi các thành viên được định nghĩa bên ngoài lớp (bao gồm định nghĩa thành viên dữ liệu tĩnh, định nghĩa lớp lồng nhau, định nghĩa hàm thành viên (bao gồm phần tử hàm thành viên) , đối với hàm xây dựng (12.1), bộ khởi tạo ctor (12.6.2)) và bất kỳ phần nào của decla phần rator của các định nghĩa như sau theo định danh, bao gồm một mệnh đề khai báo tham số và bất kỳ đối số mặc định nào (8.3.6). [Ví dụ:

Ví dụ tương tự như của bạn (sử dụng enum thay vì một static const int):

typedef int c; 
enum { i = 1 }; 
class X { 
    char v[i]; // error: i refers to ::i 
        // but when reevaluated is X::i 
    int f() { return sizeof(c); } // OK X::c 
    char c; 
    enum { i = 2 }; 
}; 

Đồng thời v[i] đang gặp phải, trình biên dịch chỉ biết về enum { i = 1 }; (hoặc static const int i = 3;, nhưng khi tuyên bố lớp học đầy đủ được biết, char v[i] sẽ khác nhau vì i sẽ được đánh giá lại thành 2.

1

Kích thước mảng phải là 3 trong là trường hợp. Nếu bạn nhìn vào dòng mã của bạn bằng dòng. Compliler không biết gì về X :: i khi xây dựng mảng. Nếu bạn thay đổi dòng bên trong lớp khi kích thước của mảng trở thành 2 và thứ hai tôi sẽ ẩn đầu tiên.

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