독서노트Effective_C++_조항 43: 학습 처리 템플릿화 기류의 명칭

8811 단어 effective
배경은 이렇다. 두 회사가 다른 다음에 Message Sender를 설계하여 이 두 회사에 서로 다른 메시지를 보내고 싶다. 명문으로 SendClearText를 보내는 것도 지원하고 밀문으로 SendEncryptedText를 보내는 것도 지원한다.일종의 사고방식은 동적 귀속 방법으로 Basic Message Sender를 정의하는 것이다. 그 안에 명문과 밀문을 보내는 허함수를 두 가지 방법이 있는데 그것이 바로 그의 하위 클래스인 Message Sender For CompanyA와 Message Sender For CompanyB이다. 이 두 하위 클래스에서 명문과 밀문을 보내는 허함수를 덮어쓰고 서로 다른 회사에 따라 서로 다른 메시지를 보내는 목적을 달성한다.
그러나 여기서 우리는 정적 다태적 방법을 사용하여 실현하고자 한다. 정적 다태는 바로 템플릿의 기술이고 코드는 다음과 같다.
 1 class CompanyA
 2 {
 3 public:
 4     void SendClearText(){}
 5     void SendEncryptedText(){}
 6 };
 7 
 8 
 9 class CompanyB
10 {
11 public:
12     void SendClearText(){}
13     void SendEncrypedText(){}
14 };
15 
16 template <class T>
17 class MsgSender
18 {
19 public:
20     void SendClearText(){}
21 };
22 
23 template <class T>
24 class MsgSenderWithLog: public MsgSender<T>
25 {
26 public:
27     void SendClearTextWithLog()
28     {
29         // Logs
30         SendClearText(); //              
31     }
32 };
33 
34 int main()
35 {
36     MsgSenderWithLog<CompanyA> MsgSender;
37     MsgSender.SendClearTextWithLog();
38 }

CompanyA와 CompanyB는 각자의 발송 함수가 있고 그 다음에 템플릿 클래스인 MsgSender가 있다. 이 템플릿에 정해진 매개 변수는 T이고 CompanyA나 CompanyB일 수 있다. 그러면 MsgSender를 정의할 때, 예를 들어 MsgSender나 MsgSender가 밑에 호출된 어느 회사의 발송 함수를 지정할 수 있다. 이것은 컴파일링 기간에 확정할 수 있는 일이다.
그러나 현재 새로운 문제가 하나 있다. 바로 우리가 발송 함수를 실행하기 전에 로그를 추가하는 것이 좋다는 것이다. 그러면 우리는 MsgSender를 계승하고 새로운 종류인 MsgSenderWithLog를 정의했다. 여기서 새로운 함수인 SendClearTextWithLog을 정의했고 이 함수에서 부류인 SendClearText를 호출했다.
이 코드에 대해 사실 사고방식은 여전히 매우 명확하지만 문제는 어떤 컴파일러가 이 코드를 컴파일하지 못한다는 것이다(VS2008 이후의 버전은 모두 가능하지만 이전의 버전은 시도하지 않았다). 왜?
 
템플릿 기술에 전특화된 개념이 존재하기 때문이다. 예를 들어 C회사는 명문을 보내려 하지 않는다. 즉, 이 회사는 SendEncryptedText() 인터페이스만 있고 SendClearText()가 없다는 것이다.정적 멀티태스킹을 계속 사용할 수 있도록 C사의 MsgSender에만 적용합니다.
 1 class CompanyC
 2 {
 3 public:
 4     void SendEncryptedText(){}
 5 };
 6 
 7 template <>
 8 class MsgSender<CompanyC>
 9 {
10 public:
11     void SendEncryptedText(){}
12 };

이때 호출하면:
1 MsgSenderWithLog<CompanyC> MsgSenderC;
2 MsgSenderC.SendClearTextWithLog(); //         

그러면 컴파일러가 SendClearText()의 오류를 보고합니다.일부 컴파일러는 특화된 템플릿 버전이 일반 버전과 다를 수 있음을 고려하여 계승 관계가 존재할 때 부모 클래스를 직접 호출하는 함수에 지원하지 않는 error를 제공합니다.그러나 이 error는 컴파일러와 관련된 것이지 필연적으로 나타나는 것이 아니다.
더 많은 컴파일러가 이러한 전특화 우려를 포기하도록 하기 위해 책에는 세 가지 해결 방법이 제공되었다.
방법1:
 1 void SendClearTextWithLog()
 2 {
 3     // Logs
 4     SendClearText(); //              
 5 }
 6   
 7 void SendClearTextWithLog()
 8 {
 9     // Logs
10     this->SendClearText(); //         
11 }

방법2:
하위 클래스에서 using MsgSender 선언::SendClearText;
컴파일러 보고 error의 본질은 템플릿 부류 영역을 찾지 않기 때문에 부류의 함수 이름을 using하여 컴파일러가 이를 찾도록 강요합니다.
 
방법 3:
SendClearText()를 MsgSender::SendClearText()로 지정합니다.
 
마지막으로 요약:
derived class template에서 "this->"를 통해base class templates의 구성원 이름을 가리키거나 "base class 자격 수식자"를 명확하게 작성해서 완성할 수 있습니다.

좋은 웹페이지 즐겨찾기