2010-04-22 44 views
16

HI,Câu hỏi về C++ lớp bên

Trong C++ lớp bên trong,

class A { 
    public: 
     void f1(); 
    private: 
     void f2(); 
    class B { 
     private void f3(); 
    }; 

} 

Liệu một lớp bên trong (B) có một con trỏ tới lớp cha của nó (A)? (giống như trong Java). Và B có thể gọi phương thức công khai/riêng của lớp cha mẹ (giống như trong Java).

Cảm ơn bạn.

Trả lời

28

Không - trong C++, các lớp lồng nhau chỉ ảnh hưởng đến tên và khả năng hiển thị chứ không ảnh hưởng đến ngữ nghĩa của chính lớp đó. Theo như mã được tạo ra, lớp lồng nhau không khác với lớp không lồng nhau.

Tất cả những gì đã thay đổi là khả năng hiển thị và tên (ví dụ: nếu nó ở trong một phần private: của lớp ngoài, nó không hiển thị với thế giới bên ngoài, và nếu nó ở trong phần public:, nó có thể nhìn thấy, nhưng (tất nhiên) để đặt tên cho nó, bạn sử dụng outer_class::inner_class. Nó vẫn là một lớp hoàn toàn riêng biệt - ví dụ, bạn có thể tạo một thể hiện của lớp bên trong mà không tạo ra bất kỳ cá thể nào của lớp bên ngoài. Trong C++ 0x, lớp bên trong không có quyền truy cập vào các phần riêng của lớp ngoài - về bản chất, nó giống như lớp bên ngoài đã khai báo lớp bên trong là bạn của nó, vì vậy tên riêng sẽ hiển thị, nhưng bạn vẫn cần phải vượt qua nó một cái gì đó giống như tham chiếu đến đối tượng của lớp bên ngoài trước khi nó có thể gọi bất kỳ hàm thành viên không tĩnh nào của lớp bên ngoài.

Mặc dù đây không phải là trường hợp được nêu ra, tôi tin rằng hầu hết các trình biên dịch thực hiện phần đặc biệt này.

+4

Dường như điều này đang thay đổi trong C++ 0x. C++ 03 nói: "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 vào các thành viên của một lớp kèm theo." C++ 0x FCD nói: "Một lớp lồng nhau là một thành viên và như vậy có quyền truy cập giống như bất kỳ thành viên nào khác." (cả §11.8/1). (Sự thay đổi được giới thiệu bởi các khiếm khuyết CWG 45 và 494: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45 và http://www.open-std.org/ jtc1/sc22/wg21/docs/cwg_defects.html # 494) –

+0

Tốt - loại bỏ sự thôi thúc để viết 'lớp người bạn {', được hỗ trợ bởi một số trình biên dịch, nhưng không rõ ràng làm cho lớp lồng nhau không phải là thành viên! – Potatoswatter

+1

@Potato: Thật thú vị, ngay cả Comeau ở chế độ C++ 03 nghiêm ngặt cũng không tuân theo ngôn ngữ C++ 03. Điều này khiến tôi tin rằng (a) có khả năng là không thể vì lý do nào đó để tuân theo ngôn ngữ C++ 03 (mặc dù tôi chưa biết tại sao, chính xác, bên cạnh những gì được đề cập trong các DR liên kết ở trên), và (b) có khả năng là không ai thực sự tuân theo ngôn ngữ C++ 03 :-). –

7

Không, lớp B không có con trỏ đến lớp A, trừ khi bạn thêm nó một cách rõ ràng.

0

Liệu nó có một con trỏ đến phụ huynh: Số
Liệu nó có quyền truy cập đến các thành viên tin cha mẹ: Sắp xếp các

Tôi nghĩ rằng nếu nó có quyền truy cập không được xác định rõ trong tiêu chuẩn tôi có thể sai rồi.
Nhưng bạn có thể truy cập nó trong g + +

#include <iostream> 

class X 
{ 
    class Y 
    { 
     public: 
      Y(X* p) 
       :parent(p) 
      {} 
      void TryY() 
      { 
       // Access a private member of X 
       ++(parent->value); 
      } 

     private: 
      X* parent; 
    }; 

    public: 
     X() 
      :y(this) 
     { 
      value = 4; 
     } 

     void TryY() 
     { 
      y.TryY(); 
      std::cout << value << std::endl; 
     } 
    private: 
     Y y; 
     int value; 

}; 

int main() 
{ 
    X x; 
    x.TryY(); 
} 
+0

Hành vi không đúng đối với C++ 03 theo * §11.8/1 *. –