Featured image of post 8. 상속

8. 상속

C++ 기본 문법

# 상속(Inheritance)

부모 클래스(KR) = super class(JAVA) = Base class(C++) 기본 클래스
자식 클래스(KR) = sub class(JAVA) = Derived class(C++) 파생 클래스

  • 클래스 사이에서 상속관계 정의
  • 기본 클래스의 속성과 기능을 파생 클래스에 물려주는 것
  • 기본 클래스에서 파생 클래스로 갈수록 클래스의 개념이 구체화
  • 다중 상속을 통한 클래스의 재활용성 높임

# 파생된 클래스로부터 객체 생성 과정

일반 : 메모리 공간 할당 -> 생성자 호출 및 실행

상속받은 클래스 : 메모리 공간 할당 -> 파생클래스의 생성자 호출 -> 기본 클래스의 생성자 호출 및 실행 -> 파생 클래스의 생성자 실행

# 파생된 클래스로부터 객체 소멸 과정

파생클래스의 소멸자 호출 및 실행 -> Base클래스의 소멸자 호출 및 실행 -> 메모리 공간 해제

Derived 클래스로부터 객체 생성 시 Base 클래스의 생성자를 명시적으로 호출하고 싶다 > 멤버 이니셜라이저 이용

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

class A
{
public:
	A() { cout << "생성자 A" << endl; }
	A(int x) { cout << "매개변수 생성자A" << endl; }
};

class B : public A
{
public:
	B():A(1){ cout << "생성자 B" << endl; }
    //멤버 이니셜라이저를 통해 매개변수 생성자 A 호출 및 실행
};


int main(void)
{
	B b;

	return 0;
}

# 상속 예제

 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
32
33
34
35
36
37
38
#include <iostream>
using namespace std;

class Person {
	char* name;
	int age;
public:
	Person(const char* _name, int age) {
		name = new char[strlen(_name) + 1];
		strcpy_s(name, strlen(_name) + 1, _name);
		this->age = age;
	}
	void Show() {
		cout << "이름 : "<< name << " 나이 : " << age << ' ';
	}
};


class UnivStudent : public Person {
	char* major;
public:
	UnivStudent(const char* name, int age ,const char* _major):Person(name, age) {
		major = new char[strlen(_major) + 1];
		strcpy_s(major, strlen(_major) + 1, _major);
	}
	void WhoAreYou() {
		Show();
		cout << "전공 : " << major << endl;
	}
};


int main(void)
{
	UnivStudent kim("kim", 21, "AI");
	kim.WhoAreYou();
	return 0;
}

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
using namespace std;

class Car {
	int gas;
public:
	Car(int gas) {
		this->gas = gas;
	}

	void ShowCurrentGas() {
		cout << "잔여 가솔린 : " << gas << endl;
	};
};

class HybridCar : public Car {
	int elec;
public:
	HybridCar(int gas, int elec) :Car(gas) {
		this->elec = elec;
	}

	void ShowCurrentElec() {
		cout << "잔여 전기량 : " << elec << endl;
	};
};

class HybridWaterCar : public HybridCar {
	int water;
public:
	HybridWaterCar(int gas, int elec, int water):HybridCar(gas, elec) {
		this->water = water;
	}

	void ShowCurrentGauge() {
		ShowCurrentGas();
		ShowCurrentElec();
		cout << "잔여 워터량 : " << water << endl;
	};
};


int main(void)
{
	HybridWaterCar drive(80, 100, 100);
	drive.ShowCurrentGauge();

	return 0;
}

# 접근지정자

public : 외부접근(다른 클래스, main()함수) + 내부접근

protected : 내부접근, 외부접근 일부(자식 클래스에서는)

private : 내부접근

상속 지정 : public 상속을 받아야 protected와 public을 그대로 물려받아 main에서 호출이 가능하다.

상속지정 Base멤버 public protected private
private 접근금지 접근금지 접근금지
protected protected protected private
public public protected private

멤버변수 : private 선언

멤버함수 : public 선언

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//상속 예시
#include <iostream>
using namespace std;

class Book {
	char* title;
	char* isbn;
	int price;
public:
	Book(const char* title, const char* isbn, int price) {
		this->title = new char[strlen(title) + 1];
		strcpy_s(this->title, strlen(title) + 1, title);
		this->isbn = new char[strlen(isbn) + 1];
		strcpy_s(this->isbn, strlen(isbn) + 1, isbn);
		this->price = price;
	}
	~Book() {
		delete[] title;
		delete[] isbn;
	}
	void ShowBookInfo() {
		cout << "책 제목 : " << title << endl;
		cout << "ISBN : " << isbn << endl;
		cout << "가격 : " << price << endl;
	}
};

class Ebook :public Book {
	char* DRMKey;
public:
	Ebook(const char* title, const char* isbn, int price, const char* DRMKey) :Book(title, isbn, price) {
		this->DRMKey = new char[strlen(DRMKey) + 1];
		strcpy_s(this->DRMKey, strlen(DRMKey) + 1, DRMKey);
	}
	~Ebook() {
		delete[] DRMKey;
	}
	void ShowEBookInfo() {
		ShowBookInfo();
		cout << "DRMKey : " << DRMKey << endl;
	}
};

int main(void)
{
	Book book("좋은 C++", "555-12345-890-0", 20000);
	book.ShowBookInfo();

	cout << endl;
	Ebook ebook("좋은 C++ ebook", "555-12345-890-1", 10000, "fdx9w0i8kiw");
	ebook.ShowEBookInfo();

	return 0;
}

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//컨트롤 클래스 예제
#include <iostream>
using namespace std;

class PermanentWorker {
	char name[20];
	int salary;
public:
	PermanentWorker(const char name[20] = "anonymous", int salary = 0) {
		strcpy_s(this->name, 20, name);
		this->salary = salary;
	}

	int GetPay() {
		return salary;
	}

	void ShowSalaryInfo() {
		cout << "name : " << name << endl;
		cout << "salary : " << salary << endl;
		cout << endl;
	}
};

class EmployeeHandler //정규직 직원을 등록, 관리 클래스 ---> 컨트롤 클래스
{
	PermanentWorker* empList[50];
	int empNum;
public:
	EmployeeHandler() {
		empNum = 0;
	}
        ~EmployeeHandler() {
            for (int i = 0; i < empNum; i++)
            {
                delete empList[i];
            }
        }

	//직원등록
	void AddEmployee(PermanentWorker* e) //PermanentWorker* e = new PermanentWorker("kim", 1000);
	{
		empList[empNum] = e;
		empNum++;
	}

	//전 직원 월급 총합
	void ShowTotalSalary() {
		int sum = 0;
		for(int i = 0; i<empNum; i++){
			sum += empList[i]->GetPay();
		}
		cout << "전직원 월급 총합 : " << sum << endl;
	}

	//각 직원의 내역 출력
	void ShowAllSalaryInfo() {
		for (int i = 0; i < empNum; i++) {
			empList[i]->ShowSalaryInfo();
		}
	}
};

int main(void)
{
	EmployeeHandler emp;

	emp.AddEmployee(new PermanentWorker("kim", 1000));
	emp.AddEmployee(new PermanentWorker("lee", 1500));
	emp.AddEmployee(new PermanentWorker("jun", 1200));

	emp.ShowAllSalaryInfo(); //각 직원의 내역 출력
	emp.ShowTotalSalary(); //전 직원 월급총합

	return 0;
}

# 객체 포인터

객체의 주소 값을 저장하는 객체 포인터 변수

C++에서, AAA형 포인터 변수는 AAA 객체 또는 AAA를 직접 혹은 간접적으로 상속하는 모든 객체를 가리킬 수 있다(객체의 주소 값을 저장할 수 있다).

1
2
3
4
5
6
Person* p = new Person();
Person* p = new Student();
Person* p = new StudentWorker();

Student* s = new Student(); //가능
Student* s = new Person(); //불가
Licensed under CC BY-NC-SA 4.0
마지막 수정: Nov 13, 2023 00:00 UTC
Hugo로 만듦
JimmyStack 테마 사용 중