Hyun2and
[Effective C++] 43: 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아두자 본문
공부엔 끝이없다/Effective C++
[Effective C++] 43: 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아두자
혀니앤 2023. 7. 23. 17:14728x90
포인트
파생 클래스에서 기본 클래스 템플릿의 이름을 참조할 때는, 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
'공부엔 끝이없다 > 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 |
Comments