2017年12月29日
《その212》 アップキャストとポインタ & p.245演習7-2
アップキャストとポインタ
下のプログラムにおいて、、
・派生クラス C は、基底クラス A からの単一継承クラス、
・派生クラス D は、基底クラス A, B からの多重継承クラスです。
C c; // C型のオブジェクト c を生成
A* ptr1 = &c; // (1)
C* ptr2 = &c; // (2)
(1) 派生オブジェクト c を指すポインタの値 &c を、A* ptr1 に代入しているので、C*型から A*型へのアップキャストが行われています。
(2) &c を C* ptr2 に代入しています。キャストの必要はないので、ptr2 と &c は、当然、同じ値になります。
プログラムの出力結果を見ると、ptr1, ptr2, &c の値は、すべて同じになっています。
D d; // D型のオブジェクト d を生成
A* ptr3 = &d; // (3)
B* ptr4 = &d; // (4)
D* ptr5 = &d; // (5)
(3) 多重継承による派生オブジェクト d を指すポインタの値 &d を、A* ptr3に代入しているので、D*型から A*型へのアップキャストが行われています。
(4) 多重継承による派生オブジェクト d を指すポインタの値 &d を、B* ptr4に代入しているので、D*型から B*型へのアップキャストが行われています。
(5) &d を D* ptr5 に代入しています。キャストの必要はないので、ptr5 と &d は、当然、同じ値になります。
プログラムの出力結果を見ると、多重継承の場合は、ポインタの値が、&dとは違う値に変化する場合があることがわかります。
// ------------------------------------
#include <iostream>
using namespace std;
class A { };
class B { };
class C : public A { };
class D : public A, public B { };
int main() {
C c;
D d;
A* ptr1 = &c; // (1)
C* ptr2 = &c; // (2)
A* ptr3 = &d; // (3)
B* ptr4 = &d; // (4)
D* ptr5 = &d; // (5)
cout << "&c " << &c << '\n';
cout << "(1) " << ptr1 << '\n';
cout << "(2) " << ptr2 << "\n\n";
cout << "&d " << &d << '\n';
cout << "(3) " << ptr3 << '\n';
cout << "(4) " << ptr4 << '\n';
cout << "(5) " << ptr5 << '\n';
}
// ------------------------------------
新版明解C++中級編 p.245 演習7-2
次のクラス Derived にメンバ関数 print を追加せよ。なお、メンバ関数 print は、以下の表示を行うものとする。
[1] Base1クラスです : x = 1
[2] Base2クラスです : x = 2
[3] Derivedクラスです : y = 3
なお、[1] と [2] は、下記のプログラムで既に出力されるようになっているので、[3] の表示のみ追加すること。
// ------------------------------------
#include <iostream>
using namespace std;
// 基底クラス1
class Base1 {
public:
int x;
Base1(int a = 0) : x(a) {
cout << "Base1::xを" << x
<< "に初期化しました。\n";
}
void print() {
cout << "Base1クラスです:x = "
<< x << '\n';
}
};
// 基底クラス2
class Base2 {
public:
int x;
Base2(int a = 0) : x(a) {
cout << "Base2::xを" << x
<< "に初期化しました。\n";
}
void print() {
cout << "Base2クラスです:x = "
<< x << '\n';
}
};
// 派生クラス
class Derived
: public Base1, public Base2 {
int y;
public:
Derived(int a, int b, int c)
: y(c), Base2(a), Base1(b) {
cout << "Derived::yを" << y
<< "に初期化しました。\n";
}
void func(int a, int b) {
Base1::x = a;
Base2::x = b;
}
};
int main()
{
Derived z(1, 2, 3);
z.func(1, 2);
z.Base1::print();
z.Base2::print();
}
// ------------------------------------
以下が、解答のプログラムです。
// ------------------------------------
#include <iostream>
using namespace std;
// 基底クラス1
class Base1 {
public:
int x;
Base1(int a = 0) : x(a) {
cout << "Base1::xを" << x
<< "に初期化しました。\n";
}
void print() {
cout << "Base1クラスです:x = "
<< x << '\n';
}
};
// 基底クラス2
class Base2 {
public:
int x;
Base2(int a = 0) : x(a) {
cout << "Base2::xを" << x
<< "に初期化しました。\n";
}
void print() {
cout << "Base2クラスです:x = "
<< x << '\n';
}
};
// 派生クラス
class Derived
: public Base1, public Base2 {
int y;
public:
Derived(int a, int b, int c)
: y(c), Base2(a), Base1(b) {
cout << "Derived::yを" << y
<< "に初期化しました。\n";
}
void func(int a, int b) {
Base1::x = a;
Base2::x = b;
}
void print() {
cout << "Derivedクラスです:y = "
<< y << '\n';
}
};
int main()
{
Derived z(1, 2, 3);
z.func(1, 2);
z.Base1::print();
z.Base2::print();
z.print();
}
// ------------------------------------
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7141718
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック