2012-01-15 17 views
7

Có mã này:Tiếp cận dữ liệu thành viên private của lớp ngoài cùng trong lớp bên

#include <iostream> 

class Outer{ 
    int a; // private data member of class Outer 
public: 
    Outer(): a(55){} 
    class Inner{ 
    public: 
     void fun(Outer ob){ 
      std::cout << ob.a << std::endl; 
     } 
    }; 
}; 

int main() { 

    Outer::Inner object; 
    object.fun(Outer()); // prints 55 
    //std::cout << (Outer().a) << std::endl; error: 'int Outer::a' is private 

    return 0; 
} 

Tại sao lớp Inner có quyền truy cập vào dữ liệu thành viên tin 'a' của lớp Outer? Sau bài viết này XL C/C++ V8.0 for Linux, nó không nên biên dịch, tuy nhiên nó biên dịch trên g ++ 4.4.0.

Trả lời

4

Theo tài liệu XL C/C++ V8.0 không hỗ trợ C++ 11, hãy xem phần "Tuân thủ tiêu chuẩn ngôn ngữ".

Trình biên dịch hỗ trợ các thông số kỹ thuật ngôn ngữ lập trình sau đây cho C và C++:

  • ISO/IEC 9899: 1999 (C99)
  • ISO/IEC 9899: 1990 (gọi tắt là C89)
  • ISO/IEC 14882: 2003 (gọi tắt là tiêu chuẩn C++)
  • ISO/IEC 14882: 1998, thông số kỹ thuật chính thức đầu tiên của ngôn ngữ (gọi tắt là C++ 98)

Các tiêu chuẩn hiện hành nói (ISO/IEC 14882: 2011 11,7):

Một lớp lồng nhau là thành viên và như vậy có quyền truy cập giống như bất kỳ thành viên khác. Các thành viên của một lớp kèm theo không có quyền truy cập đặc biệt vào các thành viên của một lớp lồng nhau; các quy tắc truy cập thông thường (Điều 11) sẽ được tuân theo.

Trong tiêu chuẩn ngôn ngữ trước cho dù quyền truy cập này không được phép hoặc ít nhất là không rõ liệu có nên cho phép hay không, tùy thuộc vào diễn giải của bạn.

+0

Không, bài viết đó cũng cho biết lớp bên trong không có quyền truy cập vào lớp kèm theo. Nhưng bạn nói đúng là nó hoàn toàn hợp lệ. – hvd

+0

@hvd: Tôi nghĩ bạn đã đúng, đã chỉnh sửa. Tôi đã phải đọc lại nó một vài lần vì nó có vẻ hơi lộn xộn một chút. –

+0

Trong thực tế, nó là hoàn toàn hợp lệ, nhưng (có lẽ khi IBM viết tài liệu và trình biên dịch của nó) không hợp lệ ban đầu: nó đã được thực hiện hợp lệ bởi http://www.open-std.org/JTC1/SC22/WG21/docs /cwg_defects.html#45 – hvd

8

C++ 03 Chuẩn $ 11,8/1: [class.access.nest]

Các thành viên của một lớp lồng nhau không có quyền truy cập đặc biệt cho các thành viên của một lớp kèm theo, cũng không phải đến các lớp học hoặc các chức năng đã trao tình bạn cho một lớp học kèm theo; các quy tắc truy cập thông thường (điều 11) sẽ được tuân theo. Các thành viên của một lớp kèm theo không có quyền truy cập đặc biệt vào các thành viên của một lớp lồng nhau; các quy tắc truy cập thông thường (điều 11) sẽ được tuân theo.

Nhưng đây là một khiếm khuyết:

45. Access to nested classes

Trong C++ 11, điều này đã được khắc phục: trong 11 lớp lồng nhau C++ làm được tiếp cận với các thành viên private của lớp kèm theo (mặc dù lớp kèm theo vẫn không có quyền truy cập vào các thành viên riêng của các lớp lồng nhau).

C++ 11 Chuẩn 11,7 lớp lồng nhau: nói

Một lớp lồng nhau là thành viên và như vậy có quyền truy cập giống như bất kỳ thành viên khác. Các thành viên của một lớp kèm theo không có quyền truy cập đặc biệt vào các thành viên của một lớp lồng nhau; các quy tắc truy cập thông thường (Điều 11) sẽ được tuân theo.[

class E { 
    int x; 
    class B { }; 
    class I { 
    B b; // OK:E::I can accessE::B 
    int y; 
    void f(E* p, int i) { 
     p->x = i; // OK:E::I can accessE::x 
    } 
    }; 
    int g(I* p) { 
    return p->y; // error:I::y is private 
    } 
}; 
—end example] 

Ví dụ tương tự như một trong những bạn có trong câu hỏi và nó cho thấy rõ hành vi hợp lệ của nó.