アフィリエイト広告を利用しています

広告

posted by fanblog

2018年01月02日

《その216》 問題演習(クロスキャストの復習) p.259演習7-4


 今回の演習は、多重継承 と クロスキャストの復習問題です。

新版明解C++中級編 p.259 演習7-4
 次のプログラムに組み入れることのできる3次元クラス ThreeDimensional を抽象クラスとして定義せよ。さらに、ThreeDimensional を継承するクラスを自由に定義せよ。

// ------------------------------------
#include <string>
#include <sstream>
#include <iostream>

// 図形クラス(抽象クラス)
class Shape {
public:
virtual ~Shape() = 0;
virtual Shape* clone() const = 0;
virtual void draw() const = 0;
virtual std::string to_string() const = 0;

void print() const {
std::cout << to_string() << '\n';
draw();
}

virtual void debug() const = 0;
};
inline Shape::~Shape() { }

inline void Shape::debug() const {
std::cout << "-- デバッグ情報 --\n";
std::cout << "型:" << typeid(*this).name()
<< '\n';
std::cout << "アドレス:" << this << '\n';
}

// 挿入子の多重定義
inline std::ostream& operator<<(
std::ostream& os,
const Shape& s
) {
return os << s.to_string();
}



// 2次元クラス(抽象クラス)
class TwoDimensional {
public:
virtual ~TwoDimensional() = 0;
virtual double get_area() const = 0;
};
inline TwoDimensional::~TwoDimensional() {}



// 長方形クラス
class Rectangle
: public Shape, public TwoDimensional {
int width;
int height;

public:
Rectangle(int w, int h)
: width(w), height(h) { }

Rectangle* clone() const {
return new Rectangle(width, height);
}

void draw() const {
for (int j = 0; j < width; j++)
std::cout << "* ";
std::cout << '\n';
for (int i = 0; i < height - 2; i++) {
std::cout << "* ";
for (int j = 1; j < width - 1; j++)
std::cout << " ";
std::cout << "* \n";
}
for (int j = 0; j < width; j++)
std::cout << "* ";
std::cout << '\n';
}

double get_area() const {
return width * height;
}

std::string to_string() const {
std::ostringstream os;
os << "Rectangle(width:" << width
<< ", height:" << height << ")";
return os.str();
}

void debug() const {
Shape::debug();
}
};



int main() {

Shape* a[] = {
new Rectangle(12, 5),
new Rectangle( 8, 4),
new Rectangle(10, 3),
};

for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
std::cout << "\n◆ " << i + 1 << ".\n";
a[i]->print();

if (
TwoDimensional* p
= dynamic_cast<TwoDimensional*>(a[i])
)
std::cout << "面積 : " << p->get_area()
<< '\n';

a[i]->debug();
std::cout << '\n';
}

for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
delete a[i];
}
// ------------------------------------

 以下が、解答のプログラムです。

// ------------------------------------
#include <string>
#include <sstream>
#include <iostream>

// 図形クラス(抽象クラス)
class Shape {
public:
virtual ~Shape() = 0;
virtual Shape* clone() const = 0;
virtual void draw() const = 0;
virtual std::string to_string() const = 0;

void print() const {
std::cout << to_string() << '\n';
draw();
}

virtual void debug() const = 0;
};
inline Shape::~Shape() { }

inline void Shape::debug() const {
std::cout << "-- デバッグ情報 --\n";
std::cout << "型:" << typeid(*this).name()
<< '\n';
std::cout << "アドレス:" << this << '\n';
}

// 挿入子の多重定義
inline std::ostream& operator<<(
std::ostream& os,
const Shape& s
) {
return os << s.to_string();
}



// 2次元クラス(抽象クラス)
class TwoDimensional {
public:
virtual ~TwoDimensional() = 0;
virtual double get_area() const = 0;
};
inline TwoDimensional::~TwoDimensional() {}



// 3次元クラス(抽象クラス)
class ThreeDimensional {
public:
virtual ~ThreeDimensional() = 0;
virtual double get_volume() const = 0;
};
inline ThreeDimensional::~ThreeDimensional() {}




// 長方形クラス
class Rectangle
: public Shape, public TwoDimensional {
int width;
int height;

public:
Rectangle(int w, int h)
: width(w), height(h) { }

Rectangle* clone() const {
return new Rectangle(width, height);
}

void draw() const {
for (int j = 0; j < width; j++)
std::cout << "* ";
std::cout << '\n';
for (int i = 0; i < height - 2; i++) {
std::cout << "* ";
for (int j = 1; j < width - 1; j++)
std::cout << " ";
std::cout << "* \n";
}
for (int j = 0; j < width; j++)
std::cout << "* ";
std::cout << '\n';
}

double get_area() const {
return width * height;
}

std::string to_string() const {
std::ostringstream os;
os << "Rectangle(width:" << width
<< ", height:" << height << ")";
return os.str();
}

void debug() const {
Shape::debug();
}
};



// 立方体クラス
class Cube
: public Shape, public ThreeDimensional {
int length;
public:
Cube(int len) : length(len) { }

Cube* clone() const {
return new Cube(length);
}

void draw() const {
for (int j = 1; j < length; j++)
std::cout << " ";
for (int j = 0; j <= length - 1; j++)
std::cout << "* ";
std::cout << '\n';
for (int i = 1; i < length - 1; i++) {
for (int j = 1; j < length - i; j++)
std::cout << " ";
std::cout << "* ";
for (int j = 1; j < length - 1; j++)
std::cout << " ";
std::cout << "* ";
for (int j = 1; j < i; j++)
std::cout << " ";
std::cout << "* \n";
}
for (int j = 1; j <= length; j++)
std::cout << "* ";
for (int j = 1; j < length - 1; j++)
std::cout << " ";
std::cout << "* \n";
for (int i = 1; i < length - 1; i++) {
std::cout << "* ";
for (int j = 1; j < length - 1; j++)
std::cout << " ";
std::cout << "* ";
for (int j = 1; j < length - i - 1; j++)
std::cout << " ";
std::cout << "* \n";
}
for (int j = 1; j <= length; j++)
std::cout << "* ";
std::cout << "\n";
}

double get_volume() const {
return length * length * length;
}

std::string to_string() const {
std::ostringstream os;
os << "Cube(length:"
<< length << ")";
return os.str();
}

void debug() const {
Shape::debug();
}
};



int main() {

Shape* a[] = {
new Rectangle(12,5),
new Cube(6),
new Cube(4),
new Cube(5),
};

for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
std::cout << "\n◆ " << i + 1 << ".\n";
a[i]->print();

if (
TwoDimensional* p
= dynamic_cast<TwoDimensional*>(a[i])
)
std::cout << "面積 : " << p->get_area()
<< '\n';


if (
ThreeDimensional* p
= dynamic_cast<ThreeDimensional*>(a[i])
)
std::cout << "体積 : " << p->get_volume()
<< '\n';


a[i]->debug();
std::cout << '\n';
}

for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
delete a[i];
}
// ------------------------------------

f07_04.png


新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)





この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/7151596
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。