2011-08-26 37 views
16

Tôi đang gặp vấn đề tương tự như được mô tả trong liên kết sau đây, trong đó lớp cơ sở được thừa kế riêng cho lỗi "không thể tiếp cận trong ngữ cảnh này" khi tôi cố gắng khai báo một thành viên của lớp cơ sở trong lớp có nguồn gốc: http://bytes.com/topic/c/answers/164246-private-inheritance-renders-class-inaccessibleSự thừa kế riêng ẩn lớp cơ sở với lỗi "không truy cập được trong ngữ cảnh này"

Rõ ràng tham khảo X với :: X hoạt động trong trường hợp trên, nhưng những gì nếu mã là trong một chức năng như:

void fooby() 
{ 
    class X {}; 

    class Y : private X {}; 

    class Z : public Y 
    { 
    public: 
     X x; // compiler "inaccessible within this context" error 
    }; 
}; 

thế nào bạn có tham chiếu X trong trường hợp này không?

Nếu fooby là cấu trúc/lớp, thì :: fooby :: X sẽ hoạt động nhưng tôi không chắc chắn cách thực hiện trong trường hợp trên.

+0

Bạn đang cố gắng làm gì với cả thành viên và lớp cơ sở cùng loại? Có lẽ điều đó sẽ giúp với một gợi ý thay thế. –

+0

@Mark B - đây chỉ là một ví dụ đơn giản để minh họa cho hành vi mà tôi đang cố gắng hiểu –

Trả lời

10

Vấn đề mà bạn đang phải đối mặt là có một định danh tiêm X trong Y (và tất cả các loại có nguồn gốc) mà đề cập đến X, mà không phải là truy cập dưới đây Y.

trong trường hợp chung của người sử dụng định nghĩa loại được công bố ở mức namespace, bạn có thể sử dụng không gian tên để đủ điều kiện loại và truy cập:

class X {}; 
class Y : X {}; 
class Z : Y { 
    ::X x;   // or Namespace::X 
}; 

Bởi vì bạn ar e xác định các loại của bạn bên trong một hàm không phải là một tùy chọn hợp lệ.

Ngoài ra, bạn có thể giải quyết vấn đề với các cách giải quyết khác. Như @Eugene đề xuất, bạn có thể tạo một định danh thay thế để ám chỉ X:

typedef class X {} another_name; 
class Y : X {}; 
class Z : Y { 
    another_name x; 
}; 

Hoặc bạn có thể thêm một typedef bên Y để cung cấp các loại các loại có nguồn gốc:

class X {}; 
class Y : X { 
public: 
    typedef X X; 
}; 
class Z : Y { 
    X x; 
}; 

Tùy chọn cuối cùng này hoạt động bởi vì nó sẽ thêm một số nhận dạng X bên trong Ypublic và đề cập đến loại, do đó trình biên dịch sẽ tìm thấy loại đó và sử dụng trong Z.

+0

+1 câu trả lời tuyệt vời và tôi đã học về cách sử dụng 'lớp' theo một cách khác ngày hôm nay. –

+0

"Tùy chọn tiếp theo" ("class X x;") của bạn là sai. Điều đó sẽ không hoạt động - nó chỉ giống nhau và đề cập đến tên lớp được tiêm tư nhân thừa kế và do đó không thể tiếp cận. Bạn có vẻ là quan niệm sai lầm rằng tên lớp được tiêm là một đối tượng chứ không phải là một loại. Tên lớp được tiêm tham chiếu đến một lớp và là một tên kiểu. –

+0

@ Johannes: Vâng, bạn đúng khi tôi có quan niệm sai lầm đó. Tôi đã thực sự cố gắng tìm kiếm điều này trong tiêu chuẩn (g ++ chấp nhận nó 4.2/4.7, nhưng clang ++ và comeau từ chối nó). Dường như cả hai 'lớp X x; 'và' nhận dạng :: type' đều thất bại. –

9

Câu hỏi hay, tôi không thể tìm cách để làm điều đó. Lựa chọn duy nhất tôi thấy là để giới thiệu typedef bên ngoài của Z:

typedef X PITA; 
class Z : public Y 
{ 
public: 
    PITA x; // ok 
}; 
Các vấn đề liên quan