CPP04 1.0
|
EX03 の課題文にある「Interfaces don’t exist in C++98 (not even in C++20).」という一文は、C++ における「インターフェース」という言葉の扱い方と、それが他の言語とどう異なるかを理解する上で非常に重要です。
まず、この文の前提を理解しましょう。
Java や C# には、interface という専用のキーワードが存在します。
- インターフェースは、抽象メソッド(実装を持たないメソッド)の宣言のみを含み、フィールド(データメンバ)を持つことはできません。
- クラスは複数のインターフェースを実装できます。
- これは、純粋に「契約」や「型」の定義に特化しています。
C++ には interface という専用のキーワードは存在しません。 C++20 になっても、これは変わっていません。
しかし、C++ で Java や C# のインターフェースと同じような機能、つまり「クラスが備えるべき振る舞いだけを定義し、実装を持たない契約」を実現する方法はあります。それが**「純粋抽象クラス」**です。
「純粋抽象クラス」とは、以下の条件を満たす C++ の抽象クラスのことです。
2. データメンバ(フィールド)を持たない。コンストラクタは純粋仮想関数にできませんが、通常は protected や private にして直接インスタンス化されないようにします。
3. 仮想デストラクタを持つ (virtual ~ClassName() {})。Java/C# のインターフェースのように、データメンバを持たないことで、振る舞いの定義に徹します。
ポリモーフィックな利用(基底クラスのポインタで派生クラスのオブジェクトを扱う)を想定しているため、デストラクタは仮想にするのが必須のベストプラクティスです。
EX03 の課題で提供された ICharacter や IMateriaSource が、まさに C++ におけるこの「純粋抽象クラス」によるインターフェースの例です。
++class ICharacter{public:// ... 他のメソッドも純粋仮想関数};An interface for any character that can interact with Materias.Definition ICharacter.hpp:46virtual std::string const & getName() const =0Gets the name of the character. This is a pure virtual function, requiring derived classes to impleme...virtual ~ICharacter()Virtual destructor for the ICharacter interface. Ensures proper cleanup of derived class objects when...Definition ICharacter.hpp:53virtual void equip(AMateria *m)=0Equips a Materia to the character's inventory. This is a pure virtual function, requiring derived cla...ICharacter はデータメンバを持たず、全ての非静的メンバ関数が純粋仮想関数です(デストラクタは実装を持つけれど、インターフェースの要件として許容されることが多い)。これが C++ での「インターフェース」の実装方法です。
課題文が「Interfaces don’t exist in C++98 (not even in C++20).」とあえて強調しているのは、以下の理由からです。
2. 設計意図の強調:C++ には interface という予約語や専用の構文がないため、Java や C# のように言語レベルで「インターフェース」として特別扱いされているわけではない、という事実を明確にしています。
interface キーワードがないため、C++ では「純粋抽象クラス」も「抽象クラス」も class キーワードで定義されます。このため、プログラマがコードを読んだ際に、その class が「インターフェースとして使うことを意図した抽象クラス」なのか、それとも「一部実装を持つ抽象クラス」なのかが、明示的に interface キーワードがない分、分かりにくいことがあります。
課題文は、私たちが ICharacter や IMateriaSource を設計する際に、たとえ interface キーワードがなくても、純粋に契約のみを定義する「インターフェース」としての設計意図を持って実装すべきであることを強調しているのです。命名規則(I プレフィックス)もその意図を伝えるためのものです。
この理解が、C++ のオブジェクト指向設計における「インターフェース」の役割を深める上で役立つはずです。