5. private 基底になりま f す。struct なら public 基底になります。
上で述べたのは public 基底の場合の話です。private 基底や
protected 基底は特に普通の設計では使わないので省きます。
6. 2 アップキャスト
list 2 upcast0.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class
class
class
class
Base {};
Derived0 : private Base {};
Derived1 : protected Base {};
Derived2 : public Base {};
int main(int , char **) {
Derived0 d0;
Derived1 d1;
Derived2 d2;
Base &a0 = d0; // error : ‘’ Base is an inaccessible base of ‘’ Derived0
Base &a1 = d1; // error : ‘’ Base is an inaccessible base of ‘’ Derived1
Base &a2 = d2; // OK
}
基底クラスのリファレンスには、派生クラスのインスタンス
を代入することができます。これをアップキャストと言い
ます。
22. list 6 diamond0.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# include <iostream >
class A
public :
int
};
class B
public :
int
};
class C
public :
int
};
class D
{
f() { return 0; }
:
public A {
f() { return 1; }
: public A {
f() { return 2; }
: public B, public C {
};
int main(int , char **) {
D d;
A &a = d;
std :: cout << d.f() << std :: endl; // ?!
}
このような不思議な状況が発生しえます。継承グラフが木構
造になっていないこのような状況をダイアモンド継承と言い
24. list 7 diamond1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# include <iostream >
class A {
public :
virtual int f() { return 0; }
};
class B : virtual public A {
public :
int f() override { return 1; }
};
class C : virtual public A {
public :
int f() override { return 2; }
};
class D : public B, public C {
};
int main(int , char **) {
D d;
A &a = d;
std :: cout << d.f() << std :: endl; // ?!
}