C++ でのオブジェクトスライス

胡金庫 2023年10月12日
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 クラスから派生した PoliticianAthlete の 2つのクラスを定義しています。したがって、Politician オブジェクトを Person に割り当てることはできますが、その逆はできません。割り当てが完了すると、新しく作成された p0 オブジェクトでメンバー関数 getParty にアクセスできなくなります。その結果、次のバージョンのコードでは、p0Politician クラスのメンバーを呼び出すため、コンパイル時エラーが発生します。

#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;
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Class