継承クラス間での名前競合
1. 派生クラスにおける同名メンバー変数の定義
2. 派生クラスのメンバーによる基底クラス同名メンバーの隠蔽
3. 基底クラスの同名メンバーの存在維持
4. スコープ解決演算子(::)による基底クラス同名メンバーへのアクセス
#include <iostream>
using namespace std;
class Base
{
public:
int value;
Base()
{
cout << "Base.valueのアドレス: " << &value << endl;
}
};
class Derived : public Base
{
public:
int value;
Derived()
{
cout << "Derived.valueのアドレス: " << &value << endl;
}
};
int main()
{
Derived d;
d.value = 2000;//派生クラスのメンバーにアクセス
d.Base::value = 200;//スコープ解決演算子で基底クラスの同名メンバーにアクセス
cout << endl;
cout << "d.valueのアドレス: " << &d.value << endl;
cout << "d.valueの値: " << d.value << endl;
cout << endl;
cout << "d.Base::valueのアドレス: " << &d.Base::value << endl;
cout << "d.Base::valueの値: " << d.Base::value << endl;
return 0;
}
//実行結果
/*
Base.valueのアドレス: 0x7ffee1b2b8d8
Derived.valueのアドレス: 0x7ffee1b2b8dc
d.valueのアドレス: 0x7ffee1b2b8dc
d.valueの値: 2000
d.Base::valueのアドレス: 0x7ffee1b2b8d8
d.Base::valueの値: 200
*/
オーバーロードの再考察
1. クラスメンバー関数のオーバーロード
(1)オーバーロード関数は本質的に異なる複数の関数
(2)関数名とパラメータリストが一意の識別子
(3)関数オーバーロードは同一スコープ内でのみ発生
2. 基底クラスと派生クラスの同名関数
(1)派生クラスの関数が基底クラスの関数を隠蔽
(2)派生クラスは基底クラスのメンバー関数をオーバーロードできない
(3)スコープ解決演算子で基底クラスの同名関数にアクセス
(4)派生クラスは基底クラスと完全に同一の関数を定義可能
#include <iostream>
using namespace std;
class Base
{
public:
int value;
void increment(int v)
{
value += v;
}
void increment(int x, int y)
{
value += (x + y);
}
};
class Derived : public Base
{
public:
int value;
void increment(int v)
{
value += v;
}
void increment(int x, int y, int z)
{
value += (x + y + z);
}
};
int main()
{
Derived d;
d.value = 2000;
d.Base::value = 200;
cout << "d.value = " << d.value << endl;
cout << "d.Base::value = " << d.Base::value << endl;
d.increment(2);
d.Base::increment(2);
cout << "d.value = " << d.value << endl;
cout << "d.Base::value = " << d.Base::value << endl;
// d.increment(2, 3); //コンパイルエラー:派生クラスにこの関数は存在しない
//派生クラスに一つでも同名関数が存在すると、基底クラスの全ての同名関数が隠蔽される
d.Base::increment(2, 3);
cout << "d.Base::value = " << d.Base::value << endl;
return 0;
}
//実行結果
/*
d.value = 2000
d.Base::value = 200
d.value = 2002
d.Base::value = 202
d.Base::value = 207
*/
まとめ
1. 派生クラスは基底クラスの同名メンバーを定義できる
2. 派生クラスのメンバーは基底クラスの同名メンバーを隠蔽する
3. 派生クラスと基底クラスの関数はオーバーロード関係を構成しない
4. 派生クラスは基底クラスと完全に同一のメンバー関数を定義できる
5. スコープ解決演算子で基底クラスの同名メンバーにアクセスする