2015-07-13 26 views
19

Tôi có đoạn mã sau:g ++ lỗi biên dịch "... được bảo vệ từ bên trong bối cảnh này", trong khi không có lỗi với kêu vang

#include <iostream> 

class BaseClass { 
protected: 
static int x; 
}; 

int BaseClass::x; 

class DerivedA: public BaseClass { 
public: 
    DerivedA() { 
     x = 3; 
    } 
};  

class DerivedB: public BaseClass { 
public: 
    DerivedB() { 
     std::cout << DerivedA::x; 
    } 
}; 

int main(int argc, char* argv[]) { 
     DerivedB b; 
} 

Biên soạn với g ++ (g++ classtest.cpp) Tôi nhận được lỗi sau:

classtest.cpp: In constructor ‘DerivedB::DerivedB()’:
classtest.cpp:9:5: error: ‘int BaseClass::x’ is protected
int BaseClass::x;
^ classtest.cpp:25:32: error: within this context
std::cout << DerivedA::x;

Khi tôi biên dịch bằng tiếng kêu ++ (clang++ classtest.cpp) không có lỗi.

Tại sao g ++ trả về lỗi biên dịch?

Tôi sử dụng phiên bản g ++ 5.1.0 và phiên bản clang ++ 3.6.1

+4

Nó cũng biên dịch trong MVS2015 – Zereges

+1

Tôi ngạc nhiên hơn rằng kêu vang ** không ** ném một lỗi ... Nhưng tôi có thể xác nhận, nó không phải. –

+2

@DrewDormann Tại sao? Tôi ngạc nhiên bởi lỗi: mặc dù 'DerivedA ::', nó thực sự truy cập vào một thành viên được bảo vệ của 'BaseClass', từ một lớp có nguồn gốc từ' BaseClass'. – hvd

Trả lời

17

Lỗi GCC. [Class.access.base]/p5:

A member m is accessible at the point R when named in class N if

  • m as a member of N is public, or
  • m as a member of N is private, and R occurs in a member or friend of class N , or
  • m as a member of N is protected, and R occurs in a member or friend of class N , or in a member of a class P derived from N , where m as a member of P is public, private, or protected, or
  • there exists a base class B of N that is accessible at R , and m is accessible at R when named in class B .

NDerivedA, mx, R là các nhà xây dựng của DerivedB. Có tồn tại một lớp cơ sở BaseClass của DerivedA có thể truy cập tại R, và x có tên trong lớp BaseClass (ví dụ: BaseClass::x) là rõ ràng thể truy cập tại R, vậy theo quan điểm viên đạn thứ tư, DerivedA::x có thể truy cập tại R.

+1

Thats một lỗi helluva. Mặc dù viên đạn được đề cập không phải là phổ biến nhất, nhưng nó không bị che khuất bởi bất kỳ phương tiện nào. –

+6

Không thể tìm thấy điều này trên bugzilla của gcc - muốn gửi? – Barry

+3

Cảm ơn bạn đã giải thích rõ ràng. Quá tệ, chúng tôi không thể cung cấp tiền thưởng cho các công việc, chẳng hạn như mở một báo cáo lỗi: – Dreamcooled

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