明示的なインタフェース(ケース1;抽象クラスへのポインタ)を使用した暗黙のインタフェース(ケース2と3;テンプレート)の使用の利点/欠点は次のとおりですか?暗黙的対明示的なインタフェース
変化しないコード:
class CoolClass
{
public:
virtual void doSomethingCool() = 0;
virtual void worthless() = 0;
};
class CoolA : public CoolClass
{
public:
virtual void doSomethingCool()
{ /* Do cool stuff that an A would do */ }
virtual void worthless()
{ /* Worthless, but must be implemented */ }
};
class CoolB : public CoolClass
{
public:
virtual void doSomethingCool()
{ /* Do cool stuff that a B would do */ }
virtual void worthless()
{ /* Worthless, but must be implemented */ }
};
ケース1:明示的なインタフェースを提供する基底クラスのポインタをとる非テンプレートクラス:
class CoolClassUser
{
public:
void useCoolClass(CoolClass * coolClass)
{ coolClass.doSomethingCool(); }
};
int main()
{
CoolClass * c1 = new CoolA;
CoolClass * c2 = new CoolB;
CoolClassUser user;
user.useCoolClass(c1);
user.useCoolClass(c2);
return 0;
}
ケース2:
template <typename T>
class CoolClassUser
{
public:
void useCoolClass(T * coolClass)
{ coolClass->doSomethingCool(); }
};
int main()
{
CoolClass * c1 = new CoolA;
CoolClass * c2 = new CoolB;
CoolClassUser<CoolClass> user;
user.useCoolClass(c1);
user.useCoolClass(c2);
return 0;
}
ケース3:テンプレートを持つクラステンプレートのクラス
class RandomClass
{
public:
void doSomethingCool()
{ /* Do cool stuff that a RandomClass would do */ }
// I don't have to implement worthless()! Na na na na na!
};
template <typename T>
class CoolClassUser
{
public:
void useCoolClass(T * coolClass)
{ coolClass->doSomethingCool(); }
};
int main()
{
RandomClass * c1 = new RandomClass;
RandomClass * c2 = new RandomClass;
CoolClassUser<RandomClass> user;
user.useCoolClass(c1);
user.useCoolClass(c2);
return 0;
}
ケース1は、オブジェクトが useCoolClass(に渡されることを必要とする)はCoolClassの子である(および価値を実装(:食べたタイプではないCoolClass由来する暗黙のインターフェース(この時間を、提供します))。一方、ケース2および3は、のいずれかのクラスを持ち、 doSomethingCool()関数を持ちます。
コードのユーザーは常にCoolClass細かいサブクラス化た場合 CoolClassUserは常に CoolClassの実装を期待されるので、その後、ケース1は、直感的に理にかなっています。しかし、このコードがAPIフレームワークの一部であると仮定して、ユーザーが CoolClassのサブクラス化を行うか、または doSomethingCool()関数を持つ独自のクラスをロールするかどうかは予測できません。
いくつかの関連記事:
https://stackoverflow.com/a/7264550/635125
https://stackoverflow.com/a/7264689/635125
https://stackoverflow.com/a/8009872/635125
ケース1とケース2はコンパイルされません。ポインタの初期化は間違った方法で行われます。 – Novelocrat
@Novelocratが修正されました。 –