category: C / C++
DATE : 2006/09/28 (Thu)
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
●この記事にコメントする
忍者ブログ [PR]
 
