C++ でのオブジェクトスライス
この記事では、C++ でのオブジェクトスライスを紹介します。
C++ の基本クラスへの派生クラスオブジェクトへのオブジェクトスライシングの使用
オブジェクト指向プログラミングのコアコンセプトは継承です。これは、クラスを相互に関連付けて階層を形成できることを意味します。階層のルートは一般に基本クラスと呼ばれ、そこから他のクラスがデータメンバーまたは関数の形式で機能を継承します。他のクラスから継承するクラスは、派生クラスと呼ばれます。基本クラスメンバーのアクセス制御を指定し、派生クラスでアクセスできる継承にはさまざまなタイプがあります。たとえば、基本クラスのプライベートメンバーには、派生クラスから直接アクセスすることはできません。代わりに、派生クラスは public
メソッドを使用してこれらのメンバーを取得する必要があります。基本クラスは、派生クラスから直接アクセスできる protected
識別子を持つメンバーの個別のセットを指定できます。
この場合、派生からベースへの変換ルールとそのような機能のユースケースに焦点を当てます。通常、派生クラスには、派生クラス自体で定義された非静的メンバーと、他のクラスから継承されたすべてのメンバーが含まれます。派生オブジェクトが基本クラスオブジェクトに割り当てられると、割り当て演算子の実行が基本クラスから取得されます。したがって、この演算子は基本クラスのメンバーのみを認識し、割り当て操作中にそれらのメンバーのみがコピーされます。
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
class Person {
protected:
string name;
public:
explicit Person(string s) : name(std::move(s)) {}
string getName() { return name; };
};
class Athlete : public Person {
string sport;
public:
explicit Athlete(string s) : Person(std::move(s)){};
Athlete(string s, string sp) : Person(std::move(s)), sport(std::move(sp)){};
string getSport() { return sport; }
};
class Politician : public Person {
string party;
public:
explicit Politician(string s) : Person(std::move(s)) {}
Politician(string s, string p) : Person(std::move(s)), party(std::move(p)) {}
string getParty() { return party; }
};
int main() {
Politician p1("Lua", "D");
Athlete a1("Lebron", "LA Lakers");
cout << p1.getName() << " " << p1.getParty() << endl;
Person p0 = p1;
Athlete a2(p0.getName());
cout << p0.getName() << endl;
cout << a2.getName() << endl;
return EXIT_SUCCESS;
}
出力:
Lua D
Lua
前のサンプルコードは、Person
クラスから派生した Politician
と Athlete
の 2つのクラスを定義しています。したがって、Politician
オブジェクトを Person
に割り当てることはできますが、その逆はできません。割り当てが完了すると、新しく作成された p0
オブジェクトでメンバー関数 getParty
にアクセスできなくなります。その結果、次のバージョンのコードでは、p0
が Politician
クラスのメンバーを呼び出すため、コンパイル時エラーが発生します。
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
class Person {
protected:
string name;
public:
explicit Person(string s) : name(std::move(s)) {}
string getName() { return name; };
};
class Athlete : public Person {
string sport;
public:
explicit Athlete(string s) : Person(std::move(s)){};
Athlete(string s, string sp) : Person(std::move(s)), sport(std::move(sp)){};
string getSport() { return sport; }
};
class Politician : public Person {
string party;
public:
explicit Politician(string s) : Person(std::move(s)) {}
Politician(string s, string p) : Person(std::move(s)), party(std::move(p)) {}
string getParty() { return party; }
};
int main() {
Politician p1("Lua", "D");
Athlete a1("Lebron", "LA Lakers");
cout << p1.getName() << " " << p1.getParty() << endl;
Person p0 = p1;
Politician p2 = p0;
Politician p2 = a1;
cout << p0.getName() << " " << p0.getParty() << endl;
return EXIT_SUCCESS;
}