忍者ブログ
[172] [171] [170] [169] [168] [167] [166] [165] [164] [163] [162]

DATE : 2017/07/24 (Mon)
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


DATE : 2006/09/28 (Thu)

これから継承の方面へと日記を進めていく予定ですが、これまでのサンプルコードに問題が見つかったのでここで修正しておきます。

これまでのサンプルコードで問題点が見つかったのは、次の部分です。

Line::Line(const Line& line) :
		start(new Point(line.getStart())),
		end(new Point(line.getEnd())) {
}
Line& Line::operator=(const Line& line) {
	if (this == &line) {
		return *this;
	}

	delete this->start;
	delete this->end;

	this->start = new Point(line.getStart());
	this->end = new Point(line.getEnd());

	return *this;
}

これから先の記事では Point クラスのサブクラスが出てくる予定です。しかし、上のソースコードを見ると、Line オブジェクトのメンバとして Point オブジェクトを決め打ちで生成しています。このままでは、Point クラスのサブクラスが出てきても Line オブジェクトのコピーや代入を行うと、中身が Point クラスそのものに変化してしまいます。

そこで次のように、Point クラスにコピーコンストラクタの代わりとして clone メソッドを用意して、コンストラクタに依存しない方法で Point オブジェクトのコピーを行うようにします。

class Point {
private :
	int x;
	int y;

public :
	Point();
	Point(int x, int y);
	Point* clone() const;
	int getX() const;
	int getY() const;
};

Point::Point() : x(0), y(0) { }

Point::Point(int x, int y) : x(x), y(y) { }

Point* Point::clone() const {
	return new Point(this->x, this->y);
}

int Point::getX() const {
	return this->x;
}

int Point::getY() const {
	return this->y;
}


class Line {
private :
	const Point *start;
	const Point *end;

public :
	Line(const Point* start, const Point* end);
	Line(const Line& line);
	~Line();
	Line& operator=(const Line& line);
	const Point& getStart() const;
	const Point& getEnd() const;
};

Line::Line(const Point* start, const Point* end) :
	start(start), end(end) { }

Line::Line(const Line& line) :
		start(line.getStart().clone()),
		end(line.getEnd().clone()) {
}

Line::~Line() {
	delete this->start;
	delete this->end;
}

Line& Line::operator=(const Line& line) {
	if (this == &line) {
		return *this;
	}

	delete this->start;
	delete this->end;

	this->start = line.getStart().clone();
	this->end = line.getEnd().clone();

	return *this;
}

const Point& Line::getStart() const {
	return *(this->start);
}

const Point& Line::getEnd() const {
	return *(this->end);
}

変更点は以下の通りです。

class Point {
private :
	int x;
	int y;

public :
	Point();
	Point(int x, int y);
	Point* clone() const;
	int getX() const;
	int getY() const;
};
Point* Point::clone() const {
	return new Point(this->x, this->y);
}
Line::Line(const Line& line) :
		start(line.getStart().clone()),
		end(line.getEnd().clone()) {
}
Line& Line::operator=(const Line& line) {
	if (this == &line) {
		return *this;
	}

	delete this->start;
	delete this->end;

	this->start = line.getStart().clone();
	this->end = line.getEnd().clone();

	return *this;
}

( ´∀`)このようにしておけば、いつ Point クラスにサブクラスを作っても、Line クラスは変更しなくていいので楽ですね

(;^ω^)ちなみにもうひとつ、Line クラスのコンストラクタにヌルポインタを渡した時の動作にも問題点があります。ただこの部分は、例外処理に触れた後で解決を図ってみようと思います。

PR
●この記事にコメントする
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード
●この記事へのトラックバック
この記事にトラックバックする:
忍者ブログ [PR]
ブログ内検索
最近の状況
リンク
カレンダー
06 2017/07 08
S M T W T F S
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
使用許諾
最新コメント
(08/15)
(05/04)
(03/06)
(03/04)
(09/25)
最新トラックバック
T/O
(11/05)
ブログ内検索
最近の状況
リンク
カレンダー
06 2017/07 08
S M T W T F S
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
使用許諾
最新コメント
(08/15)
(05/04)
(03/06)
(03/04)
(09/25)
最新トラックバック
T/O
(11/05)