『Effective C++』読書ノートのitem 43:学習処理テンプレート化ベース内の名称


1.注意「オブジェクト向けC++」から「テンプレートC+++」への継承で問題が発生する可能性があります.ベースクラステンプレートが特化され、この特化バージョンでメンバーが変更される可能性があるため、C++はテンプレート化ベースクラスで継承された名前を探すことを拒否します.
2.例:情報を異なる会社に転送すると仮定し、転送方式は明文転送と密文転送を含み、テンプレート類の設計方法を採用する.
template
class MsgSender{
	public:
		...
		void sendClear(const MsgInfo& info){
			std::string msg;
			...	//      
			Company c;
			c.sendCleartext(msg);
		}
		void sendSecret(const MsgInfo& info)
			{...}		//     
};

送信時に情報を記録する機能を追加したい場合は、継承方式を採用します.
template
class LoggingMsgSender: public MsgSender{
	public:
		...
		void sendClearMsg(const MsgInfo& info){
			...	//             
			sendClear(info);	//              ,        。                 Company     ,               
			...	//             
		}
		...
};

改善方法:
(1)基本クラス関数呼び出し動作の前にthisポインタを付ける:
this->sendClear(info);		//        

(2)using宣言式を使用してクラス内でベースクラスネーミングスペースを使用する:
using MsgSender::sendClear;		//     ,        sendClear

(3)定義関数がベースクラスの関数であることを明確にする.
MsgSender::sendClear(info);		//        

3.テンプレート・クラスと似ているクラスがあるが、構造が異なる場合は、「テンプレートフル特化」を使用します.これにより、テンプレートが特定のテンプレート・パラメータ・タイプに特化されると、特化バージョンが呼び出され、フォーマットが定義されます.
template<>
class MsgSender{		//    CompanyZ        
	public:
		...
		void sendSecret(const MsgInfo& info);	//     
		...
};