抽象クラスと純粋仮想メソッド
純粋仮想メソッドでインターフェースを定義し、派生クラスの契約を強制します。
「抽象クラスと純粋仮想メソッド」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
抽象クラスとは
抽象クラスには、= 0 で宣言された純粋仮想関数が少なくとも 1 つあります。抽象クラスを直接インスタンス化することはできません。
class Animal {
public:
virtual void speak() const = 0; // pure virtual
virtual ~Animal() = default;
};
// Animal a; // ERROR: cannot instantiate純粋仮想関数
= 0 は、関数にデフォルト実装がないことを示します。クラスをインスタンス化できるようにするには、派生クラスでその関数をオーバーライドする必要があります。
インターフェースの実装
派生クラスは、すべての純粋仮想関数に具体的な本体を提供します。
class Dog : public Animal {
public:
void speak() const override {
std::cout << "Woof!\n";
}
};
Dog d;
d.speak(); // Woof!インターフェースとしての抽象クラス
純粋仮想メソッドだけを持ち、データメンバーを持たない抽象クラスは、他の言語におけるインターフェースのように機能します。
class Drawable {
public:
virtual void draw() const = 0;
virtual ~Drawable() = default;
};実装とインターフェースの組み合わせ
抽象クラスには、純粋仮想メソッドと具象メソッドの両方を持たせることができます。純粋仮想メソッドはコントラクトを定義し、具象メソッドは共有動作を提供します。
class Logger {
public:
void logInfo(const std::string& msg) { log("INFO", msg); }
void logError(const std::string& msg) { log("ERROR", msg); }
protected:
virtual void log(const std::string& level, const std::string& msg) = 0;
};デフォルト本体を持つ純粋仮想関数
純粋仮想関数にも本体を持たせることができます。これは、派生クラスが呼び出せるデフォルト実装として便利です。
class Base {
public:
virtual void f() = 0;
};
void Base::f() {
std::cout << "default behavior\n";
}
class Derived : public Base {
public:
void f() override {
Base::f(); // call the default
std::cout << "extra\n";
}
};ポインターと参照による使用
ポリモーフィックなコードでは、抽象オブジェクトを基底型へのポインターまたは参照で保持します。
void perform(const Animal& a) {
a.speak();
}コンテナへの格納
vector は抽象型を値として保持できません。ポインター、通常はスマートポインターを使用してください。
std::vector<std::unique_ptr<Animal>> zoo;
zoo.push_back(std::make_unique<Dog>());
zoo.push_back(std::make_unique<Cat>());
for (auto& a : zoo) a->speak();抽象クラスを使用する場合
次の場合に使用してください。
- 複数の無関係な実装に共通のインターフェースを定義したい
- ポリモーフィックなコンテナの基底型が必要である
- サブクラスを通じて動作を注入したい(Template Method パターン)
代替手段:Concepts とテンプレート
コンパイル時ポリモーフィズムには、C++20 の Concepts とテンプレートで抽象クラスを置き換えられることがよくあります。ランタイムコストはゼロです。ランタイムにポリモーフィズムが必要な場合は virtual を使用してください。
落とし穴:スライシング
抽象クラスは参照またはポインターで渡してください。値渡しは、抽象型をインスタンス化できないため、そもそも不可能です。ただし、派生クラスを値渡しするとスライシングが発生します。
理解度チェック
C++ でクラスを抽象クラスにするものは何ですか。
まとめ
抽象クラスは、少なくとも 1 つの純粋仮想メソッドを持ち、ポリモーフィックなコードのインターフェースを定義します。ポインターまたは参照(多くの場合はスマートポインター)で使用し、ランタイムに動作を振り分けます。
よくある質問
「抽象クラスと純粋仮想メソッド」レッスンは無料ですか?
はい。「抽象クラスと純粋仮想メソッド」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「抽象クラスと純粋仮想メソッド」で何を学びますか?
純粋仮想メソッドでインターフェースを定義し、派生クラスの契約を強制します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「抽象クラスと純粋仮想メソッド」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 単一継承と多重継承
- 仮想関数とvtable
- 抽象クラスと純粋仮想メソッド
- 継承とコンポジションのトレードオフ