-
[Effective C++] 43: 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아두자Programming/Effective C++ 2023. 7. 23. 17:14

포인트
파생 클래스에서 기본 클래스 템플릿의 이름을 참조할 때는, this-> 를 붙이거나 기본 클래스 한정문을 명시적으로 써준다
예제 코드
(대부분은 비워놓은 내부 코드들)
#include <iostream> using namespace std; class CompanyA { public : void sendCleartext(const string& msg) {}; }; class CompanyB { public: void sendCleartext(const string& msg) {}; }; class CompanyZ { public: void sendCleartext(const string& msg) {}; }; class MsgInfo { }; template<typename Company> class MsgSender { public: void SendClear(const MsgInfo& info) { string msg; Company C; C.sendCleartext(msg); } }; template<typename Company> class LoggingMsgSender : public MsgSender<Company> { public: void SendClearMsg(const MsgInfo& info) { SendClear(info); //차이가 생기는 부분! } }; template<> class MsgSender<CompanyZ> { public: void SendSecret() { } }; int main() { MsgInfo info; LoggingMsgSender<CompanyA> LMSA; LMSA.SendClearMsg(info); }위의 구조를 가진 코드에서 SendClearMsg 를 호출하면 에러가 나오는 것을 알 수 있다

C3861 : 식별자를 찾을 수 없습니다 에러가 나온다.
이유는 컴파일러가 LogginMsgSender 클래스 템플릿의 정의를 보고 어디서 파생된 것인지를 모른다는 것이다.
Company 는 템플릿 매개변수이고, 실제로는 인스턴스가 만들어질 때에서야 알게된다
MsgInfo info; LoggingMsgSender<CompanyA> LMSA; //인스턴스를 생성하면서야 CompanyA를 쓸 것임을 알게됨 LMSA.SendClearMsg(info);즉, Company 매개변수에 실제로 SendClear 가 있는지 없는지 모르겠기 때문에 그냥 컴파일 에러를 내버린다
해결방법 1
template<typename Company> class LoggingMsgSender : public MsgSender<Company> { public: void SendClearMsg(const MsgInfo& info) { this->SendClear(info); } };this-> 를 사용해 SendClear 가 상속되었고, 실제로 들어온 인스턴스의 SendClear 를 사용하겠다 ! 고 선언한다
해결방법 2
using 을 사용한다. (항목 33과 관련)
클래스의 유효범위를 컴파일러에게 전달해준다
template<typename Company> class LoggingMsgSender : public MsgSender<Company> { public: //컴파일러에게 MsgSender 안에 SendClear 를 확인하면 된다고 알려줌 using MsgSender<Company>::SendClear; void SendClearMsg(const MsgInfo& info) { SendClear(info); } };해결방법 3
호출할 함수가 기본 클래스의 함수라는 것을 명시적으로 지정한다
template<typename Company> class LoggingMsgSender : public MsgSender<Company> { public: void SendClearMsg(const MsgInfo& info) { MsgSender<Company>::SendClear(info); } };호출 함수가 가상 함수인 경우 가상 함수 바인딩이 무시된다
728x90'Programming > Effective C++' 카테고리의 다른 글
[Effective C++] 46: 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자 (0) 2023.08.06 [Effective C++] 45: "호환되는 모든 타입" 을 받아들이는 데는 멤버 함수 템플릿이 직방! (0) 2023.07.31 [Effective C++] 44: 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자 (0) 2023.07.31 [Effective C++] 1. C++ (0) 2023.02.19 [Effective C++] 0. 서론 (0) 2023.02.19