2017-11-20 15 views
2

다른 클래스 템플릿에서 파생 된 클래스 템플릿에서 보호 된 클래스 멤버에 액세스 할 때 문제가 발생합니다. 세 개의 클래스 템플릿이 있는데 두 번째 템플릿은 첫 번째 템플릿에서 파생되며 세 번째 템플릿은 두 번째 템플릿에서 파생됩니다. 구체적C++에서 클래스 템플릿 상속의 두 번째 수준에서 보호 된 클래스 멤버에 액세스 할 수 없습니다.

class1.h :

template <typename T> class class1 
{ 
protected: 
    T data; 
    int a; 
public: 
    class1(); 
    void someMethod(); 
}; 

class2.h :

#include "class1.h" 

template <typename T> class class2: public class1<T> 
{ 
    using class1<T>::a; 
    T otherData; 
public: 
    class2(); 
}; 

class3.h :

#include "class2.h" 

template <typename T> class class3: public class2<T> 
{ 
    using class2<T>::a; 
public: 
    class3(); 
}; 

class2.cpp :

#include "class2.h" 
#include <iostream> 

template <typename T> class2<T> :: class2() 
{ 
    std::cout<<"Creating class2 object!"<<std::endl; 
    a = 2; 
} 

template class class2<double>; 
,745,

마지막으로, class3.cpp는 :

#include "class3.h" 
#include <iostream> 

template <typename T> class3<T> :: class3() 
{ 
    std::cout<<"Creating class3 object!"<<std::endl; 
    a = 3; 
} 

template class class3<double>; 

나는이 같은 오브젝트 파일로 class2.cpp을 컴파일 :

g++ -c -O3 -std=c++11 -Wall -o class2.o class2.cpp 

모든 것이 잘 어울린다. 그러나 같은 방법으로 class3.cpp를 컴파일 할 때 오류가 발생합니다. 다음과 같은 오류가 나옵니다 :

In file included from class2.h:4:0, 
       from class3.h:4, 
       from class3.cpp:1: 
class3.h: In instantiation of ‘class class3<double>’: 
class3.cpp:11:16: required from here 
class1.h:9:6: error: ‘int class1<double>::a’ is protected 
    int a; 
    ^

도움이되지 않습니다 강좌 3에 using class1<T>::a;using class2<T>::a; 교체. 정확히이 오류의 원인은 무엇이며 어떻게 클래스 3에서 변수 a에 액세스해야하는지 어떻게 피할 수 있습니까? 첫 번째 수준의 상속 (class2) 이 문제를 감지하지 못하고 두 번째 클래스 (class3) 이되는 이유는 무엇입니까? 의견을 주셔서 감사합니다.

참고 : 동일한 유형의 상속을 시도했지만 템플릿이없고 using을 포함한 두 줄을 모두 제거했으며 컴파일이 원활 해졌습니다 (이제 변수 a에 대한 액세스가 클래스 3에서 허용됨). 문제는 틀림없이 템플릿과 관련이 있습니다.

+3

당신은 private 상속을 사용합니다 (디폴트'class' 상속 임),'a'는'class2'의 private 필드가되고'class3'는 접근 할 수 없습니다 : https://stackoverflow.com/questions/860339/private-public-and-protected-inheritance의 차이점 – Constructor

+0

먼저 템플릿없이 동일하게 시도 했습니까? – user0042

+0

@Constructor 상속을 할 때 키워드 "public"을 넣는 것을 잊었지만이 오타를 제거해도 문제가 해결되지 않습니다. 오류는 그대로 유지됩니다. – MajinSaha

답변

2

귀하의 class2 정의는 다음과 같다 : privateclass ES의 구성원에 대한 기본 부분이기 때문에

template <typename T> class class2: public class1<T> 
{ 
private: // default section 
    using class1<T>::a; 
    T otherData; 
public: 
    class2(); 
}; 

그것은이다. 따라서 a 회원은 여기에서 비공개로 설정되며 class3으로 상속받을 수 없습니다. 명시 적으로 protectedusing class1<T>::a; 문 또는 class2 정의의 public 섹션을 배치해야합니다 :

template <typename T> class class2: public class1<T> 
{ 
    T otherData; 
protected: // <-- added 
    using class1<T>::a; 
public: 
    class2(); 
}; 

지금이 ( class3 포함) class2 파생 클래스에서 액세스 할 수 있습니다.

+0

젠장! 그래서 그것이 문제였습니다! 필자는 항상 "using"이라는 키워드가 포함 된 줄은 일부 가시성 목적으로 만 사용되었으며 액세스 권한을 배포하지 않았다고 생각했습니다. 이제 나는 그것이 사적, 보호 적 또는 공개 여부에 관계없이 실제로 중요한지 이해합니다. 고마워요! – MajinSaha

+0

'class3'이'class1 :: a'를 사용하여 명시 적으로 말하면 왜 작동하지 않습니까? 그리고 어느 쪽이든, 오류 메시지는 더 좋을 수 있습니다. 그것은'a'가'protected'라고 선언했음을 불평합니다. –

+0

@DanielH'a'는 ('private' 섹션에'using' 문을 두었 기 때문에)'class2'에서 private이되고'class3'에서 액세스 할 수 없습니다. 'class3 '에서'using'문은 이것에 영향을 줄 수 없습니다. – Constructor