ホームに戻る
出典 :
関連 :
目次 :
委譲コンストラクタ
コンストラクタから、同じクラスの他のコンストラクタに処理を委譲する機能のこと。
コンストラクタから自身の他のコンストラクタを呼ぶことで、共通の初期化処理を一元化することができる。
C++11で追加された。
// param 構造体定義
struct Param
{
int id;
std::string name;
}
// Hoge クラス定義
class Hoge
{
private:
int m_Id;
std::string m_Name;
public:
// コンストラクタ#1
Hoge(int i, const std::string s)
: m_Id(i), m_Name(s)
{
:
}
// コンストラクタ#2
Hoge(const Param& param)
: Hoge(param.id, param.name) //< コンストラクタ#1に処理を委譲
{
:
}
}
基底クラスのコンストラクタを明示的に呼び出す
委譲コンストラクタの機能を用いることで、基底クラスのコンストラクタを明示的に指定することができる。
指定を行わなかった場合は、基底クラスのデフォルトコンストラクタ(引数なし)が呼ばれる。
// 基底クラス定義
class Base
{
public:
// デフォルトコンストラクタ
Base()
{
:
}
// コンストラクタ(引数あり)
Base(int i, const std::string s)
{
:
}
}
// 派生クラス定義
class Derived : public Base
{
public:
// コンストラクタ
Derived(int i, const std::string s)
: Base(i, s) //< 基底クラスのコンストラクタ(引数あり)を明示的に指定
{
:
}
}
上記の例では、基底クラスの引数ありコンストラクタを呼ぶために、明示的な指定を行っている。
但し、このように派生クラスから基底クラスに引数をそのまま渡す場合は、後述する継承コンストラクタを用いるほうが簡便である。
継承コンストラクタ
基底クラスで定義したコンストラクタ(群)を、派生クラスでそのまま使用できるようにするための糖衣構文。C++11で導入された。
多くの場合、派生クラスは基底クラスと共通のコンストラクタを有するため、
継承コンストラクタの導入前は、派生クラスのコンストラクタに渡された引数を基底クラスに転送する必要があった。
継承コンストラクタを用いることで、この作業が不要となる。
// 基底クラス#1定義
class Base1
{
public:
Base1()
{
:
}
Base1(int i)
{
:
}
}
// 基底クラス#2定義
class Base2
{
public:
Base2()
{
:
}
Base2(const std::string s)
{
:
}
}
// 派生クラス定義
class Derived : public Base1, Base2
{
public:
// Base1 、Base2 のコンストラクタすべてを継承することを宣言
// ⇒ Derived() 、Derived(int) 、Derived(const std::string) が暗黙的に宣言される
// (Derived(int) は Base1(int) 、
// Derived(const std::string) は Base2(const std::string) を呼び出す)
using Base1::Base1;
using Base2::Base2;
}
上記の例では、派生クラス Derived は using により、基底クラス Base1 、Base2 のコンストラクタを継承している。
Derived(int) や Derived(const std::string) はそのまま Base1(int) 、Base2(const std::string) を呼び出すため、
あらためて派生クラスのコンストラクタを定義する必要が無い。
一部を明示的に宣言
継承コンストラクタを用いた場合でも、特定のコンストラクタのみを再定義することが可能である。
派生クラスで追加の処理を行う場合や、基底クラスの異なるコンストラクタを呼び出す場合に用いる。
// 派生クラス定義
class Derived : public Base1, Base2
{
public:
using Base1::Base1;
using Base2::Base2;
// Derived::Derived(const std::string s) のみを明示的に宣言
Derived(const std::string s)
: Base2::Base2(s)
{
// (派生クラス固有の処理)
:
}
}
上記の例では、Derived は Base1 および Base2 のコンストラクタを継承しつつ、Derived(const std::string) のみはオーバーライドを行っている。
委譲コンストラクタを用いて Base2(const std::string) を呼ぶとともに、Derived 独自の処理を行うことを目論んでいる。