C++

[C/C++ 강좌] 76강. 상속이 필요한 이유 (1)

코다람쥐 2022. 1. 19. 15:57

https://www.youtube.com/watch?v=nKyJSgODsKo&list=PLlJhQXcLQBJqywc5dweQ75GBRubzPxhAk&index=81

 

1. 상속이 필요한 이유

#include <iostream>
#include <string>

using namespace std;

class Image {
public:
	operator string() {
		return "사진";
	}
};

class TextMessage {
public:
	TextMessage(int sendTime, string sendName, string text) {
		this->sendTime = sendTime;
		this->sendName = sendName;
		this->text = text;
	}

	int GetSendTime() const { return sendTime; }
	string GetSendName() const { return sendName; }
	string GetText() const { return text; }
		 
private:
	int sendTime;
	string sendName;
	string text;
};

class ImageMessage {
public:
	ImageMessage(int sendTime, string sendName, Image* image) {
		this->sendTime = sendTime;
		this->sendName = sendName;
		this->image = image;
	}

	int GetSendTime() const { return sendTime; }
	string GetSendName() const { return sendName; }
	Image *GetImage() const { return image; }
private:
	int sendTime;
	string sendName;
	Image *image;
};

int main()
{
	Image* p_dogImage = new Image();
	TextMessage* hello = new TextMessage(10, "두들", "안녕");
	ImageMessage* dog = new ImageMessage(20, "두들", p_dogImage);

	cout << "보낸 시간 : " << hello->GetSendTime() << endl;
	cout << "보낸 사람 : " << hello->GetSendName() << endl;
	cout << " 내 용  : " << hello->GetText() << endl;
	cout << endl;

	cout << "보낸 시간 : " << dog->GetSendTime() << endl;
	cout << "보낸 사람 : " << dog->GetSendName() << endl;
	cout << " 내 용  : " << (string)*dog->GetImage() << endl;
	cout << endl;

	delete hello;
	delete dog;
	delete p_dogImage;
}

 

위와 같이 TextMessage클래스와 ImageMessage클래스는 sendTime, sendName과 같이 공통으로 겹치는 멤버들이 있다. 이러한 것들을 하나의 분모로 묶고 싶을 때 상속을 사용하면 편리하다.

 

 

아래의 코드는 Message 클래스를 상속하는 방식으로 구현되었다.

#include <iostream>
#include <string>

using namespace std;

class Message {
public:
	Message(int sendTime, string sendName) {
		this->sendTime = sendTime;
		this->sendName = sendName;
	}
	int GetSendTime() const { return sendTime; }
	string GetSendName() const { return sendName; }

private:
	int sendTime;
	string sendName;
};

class Image {
public:
	operator string() {
		return "사진";
	}
};

class TextMessage : public Message{
public:
	TextMessage(int sendTime, string sendName, string text)
		: Message(sendTime, sendName)  { // 생성자 위임을 이용
		this->text = text;
	}
	string GetText() const { return text; }
		 
private:
	string text;
};

class ImageMessage : public Message {
public:
	ImageMessage(int sendTime, string sendName, Image* image)
		: Message(sendTime, sendName) { // 생성자 위임을 이용
		this->image = image;
	}

	Image *GetImage() const { return image; }
private:
	Image *image;
};

int main()
{
	Image* p_dogImage = new Image();
	TextMessage* hello = new TextMessage(10, "두들", "안녕");
	ImageMessage* dog = new ImageMessage(20, "두들", p_dogImage);

	cout << "보낸 시간 : " << hello->GetSendTime() << endl;
	cout << "보낸 사람 : " << hello->GetSendName() << endl;
	cout << " 내 용  : " << hello->GetText() << endl;
	cout << endl;

	cout << "보낸 시간 : " << dog->GetSendTime() << endl;
	cout << "보낸 사람 : " << dog->GetSendName() << endl;
	cout << " 내 용  : " << (string)*dog->GetImage() << endl;
	cout << endl;

	delete hello;
	delete dog;
	delete p_dogImage;
}

 

부모클래스의 멤버는 부모클래스에서 초기화 하는 것이 좋다.

자식클래스의 생성자는 생성자 위임과 같이 초기화를 시켜주면 좋다.

상속을 사용하는 이유 중 하나는 공통적인 멤버를 바꿔야할 때 상속을 쓰지 않으면 모든 멤버를 하나하나 찾아가면서 수정해야하지만 상속을 사용하면 부모클래스만 수정하면 그 밑에 자식클래스는 알아서 모두 수정되기 때문에 유지보수 측면에서 유리하다.

 

상속을 사용하는 또 다른 이유는 가상 함수를 배우면 나온다.