티스토리 뷰

반응형

07-1 상속에 들어가기에 앞서

 

상속(Inheritance)의 이해를 위한 이 책의 접근 방식

1단계:문제의 제시

2단계:기본개념 소개

3단계 문제의 해결

 

상속에 대한 새로운 관점의 소개

'기존에 정의해 놓은 클래스의 재활용 목적으로 만들어진 문법적 요소가 상속이다.'

->단순히 재활용 이외에 목적이 있다.

 

문제의 제시를 위한 시나리오의 도입

class PermanentWorker
{
private:
	char name[100];
	int salary;
public:
	PermanentWorker(char* name, int money)
		:salary(money)
	{
		strcpy(this->name, name);
	}
	int GetPay() const
	{
		return salary;
	}
	void ShowSalaryInfo() const
	{
		cout << "name: " << name << endl;
		cout << "salary: " << GetPay << endl; endl;
	}
};

 

데이터적 성격을 가진 클래스

 

class EmployeeHandler
{
private:
	PermanentWorker* empList[50];
	int empNum;
public:
	EmployeeHandler():empNum(0)
	{}
	void AddEmployee(PermanentWorker* emp)
	{
		empList[empNum++] = emp;
	}
	void ShowAllSalaryInfo() const
	{
		for (int i = 0; i < empNum; i++)
		{
			empList[i]->ShowSalaryInfo();
		}
	}
	void ShowTotalSalary() const
	{
		int sum = 0;
		for (int i = 0; i < empNum; i++)
			sum += empList[i]->GetPay();
		cout << "salary sum: " << sum << endl;
	}
	~EmployeeHandler()
	{
		for (int i = 0; i < empNum; i++)
			delete empList[i];
	}
};

 

기능적 특성을 가진 클래스

-새로운 직원 정보 등록

-모든 직원의 급여 정보 출력

-이번 달 급여의 총액 출력

 

컨트롤 클래스 or 핸들러 클래스

:기능의 처리를 실제로 담당하고 구체적으로 무슨 기능을 제공하는 지 알 수 있게 해주는 클래스

 

 

객체지향, 소프트웨어 설계에서 중요한점

'요구사항의 변경에 대응하는 프로그램의 유연성'

'기능의 추가에 따른 프로극램의 확장성'

 

문제의 제시

정규직 하나의 형태만 있었는데, 영업직과 임시직이 생겼다.

 

급여체계 변화

고용직 급여 -> 연봉제, 고정임금

영업직 급여 -> 기본급여+인센티브

임시직 급여 -> 시간당 급여* 일한 시간

 

그렇다면 임시직과 영업직 클래스만 추가하면 되지 않는가?

 핸들러 클래스도 새로 추가되어야하는가?

-> 최소한의 변경으로 새 클래스 추가가 '상속'을 이용하면 가능하다.

 

 

07-2 상속의 문법적인 이해

 

상속이란?

A클래스가 B클래스를 상속받는다면, B클래스는 A클래스에 있는 모든 멤버를 물려받는다.

 

상속의 방법과 그 결과

class Person

{}

 

class univStudent: public Person

-> Person 클래스에 있는 멤버를 모두 사용할 수 있다.

 

 

상속받는 클래스의 생성자 정의

class univStudent(char*myname,int myage, char*mymajor)

 :Person(myage, myname)

{

 strcpy(major, mymajor);

}

 

*UnivStudent 클래스의 생성자는 Person 클래스의 멤버까지 초기화해야한다.

*UnivStudent 클래스의 생성자는, Person 생성자를 호출해서 Person 생성자를 초기화하는 것이 좋다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;


class Person
{
private:
	int age;
	char name[50];
public:
	Person(int myage, char* myname) :age(myage)
	{
		strcpy(name, myname);
	}
	void WhatYourName() const
	{
		cout << "My name is " << name << endl;
	}
	void HowOldAreYou() const
	{
		cout << "I'm " << age << " years old" << endl;
	}

};

class UnivStudent : public Person
{
private:
	char major[50];
public:
	UnivStudent(char* myname, int myage, char* mymajor)
		:Person(myage, myname)
	{
		strcpy(major, mymajor);
	}
	void WhoAreYou() const
	{
		WhatYourName();
		HowOldAreYou();
		cout << "My major is " << major << endl << endl;
	}
};

int main(void)
{
	UnivStudent ustd1("Lee", 22, "Computer eng.");
	ustd1.WhoAreYou();

	UnivStudent ustd2("Yoon", 21, "Electronic eng");
	ustd1.WhoAreYou();
	return 0;

}

 

용어의 정리

Person -> UnivStudent

상위클래스 -> 하위클래스

기초클래스 -> 유도(derived)클래스

슈퍼클래스 -> 서브 클래스

부모 클래스 -> 자식 클래스

 

 

유도클래스의 객체생성 과정에서 기초클래스의 생성자는 100% 호출된다.

유도클래스의 새성자에서 기초 클래스의 생성자 호출을 명시하지 않으면, 기초 클래스의 void 호출자가 생성된다.

 

 

유도클래스 객체의 소멸과정

유도 클래스의 객체가 소멸될 때에는 유도 클래스의 소멸자가 실행되고 난 다음에 기초 클래스의 소멸자가 실행된다.

스택에 생성된 객체의 소멸순서는 생성순서와 반대이다.

 

생성자에서 동적 할당한 메모리 공간은 소멸자에서 해제한다.

 

 

07-3 protected 선언과 세 가지 형태의 상속

 

portected로 선언된 멤버가 허용하는 접근의 범위

허용하는 접근의 범위

private< protected < public

 

 

private은 접근이 불가하지만, protected는 유도클래스에서 접근이 가능하다.

 

세 가지 형태의 상속

public 상속

접근 제어 권한을 그대로 상속한다

단, private은 접근 불가로 상속한다.

 

protected 상속

protected보다 접근의 범위가 넓은 멤버는 protected로 상속한다.

단, private은 접근불가로 상속한다.

 

private 상속

private보다 접근 범위가 더 넓은 멤버는 protected로 상속한다

단 private 접근불가로 상속한다.

 

 

07-4 상속을 위한 조건

상속을 위한 기본 저긴인 IS-A의 관계의 성립

 

전화기->무선 전화기

컴퓨터-> 노트북 컴퓨터

 

무선 전화기 is a 전화기

노트북 컴퓨터 is a 컴퓨터

 

기초클래스와 유도클래스간에 IS-A 관계가 성립해야한다.

 

HAS-A 관계도 상속의 조건은 되지만 복합 관계로 이를 대신하는 것이 일반적이다.

경찰 HAS A 총

HSA A 관계는 상속이 아니라 다른 방식으로 표현한다.

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;


class Gun
{
private:
	int bullet;
public:
	Gun(int bnum) :bullet(bnum)
	{
	}
	void Shot()
	{
		cout << "BBANG" << endl;
		bullet--;
	}
};

class Police
{
private:
	int handcuffs;
	Gun* pistol;
public:
	Police(int bnum, int bcuff)
		:handcuffs(bcuff)
	{
		if (bnum > 0)
			pistol = new Gun(bnum);
		else
			pistol = NULL;
	}
	void PutHandcuff()
	{
		cout << "SNAP!" << endl;
		handcuffs--;
	}
	void Shot()
	{
		if (pistol == NULL)
			cout << "Hut Bbang!" << endl;
		else
			pistol->Shot();
	}
	~Police()
	{
		if (pistol != NULL)
			delete pistol;
	}
};

int main(void)
{
	Police pman1(5, 3);
	pman1.Shot();
	pman1.PutHandcuff();

	Police pman2(0, 3);//경찰을 소유하지 않은 경찰
	pman2.Shot();
	pman2.PutHandcuff();
	return 0;

		
}
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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
글 보관함
반응형