C++/C++ 상속

C++ 상속

재윤 2024. 1. 24. 15:49
반응형

상속(inheritance)이란?

  • “일정한 친족적 관계가 있는 사람 사이에 한 쪽이 사망하거나 법률상의 원인이 발생하였을 때 재산적 또는 친족적 권리와 의무를 계승하는 제도” 라고 네이버 사전에 정의되어 있다.
  • 부모님이 돌아가시면 부모님의 재산을 모두 물려받게 됨.
  • 그런데 이 상속이 C++에서도 존재함.

예를 들어서 설명해보자.

  • 사람이란 클래스, 학생이란 클래스가 있다고 가정
  • 사람이란 클래스 내에는 이름, 나이, 취미 등과 같은 속성과 함께, 일어나기, 잠자기, 먹기, 공부하기 등 행동이 정의되어 있음.
  • 학생이란 클래스 내에는 마찬가지로 이름, 나이, 취미, 소속, 학교와 같은 속성, 잠자기, 먹기, 공부하기 등과 같은 행동으로 정의되어 있음.
  • 그런데, 학생도 역시 사람이란 부류에 속하므로 학생은 사람에 포함됨.
  • 사람 클래스와 학생 클래스가 공통적으로 가지는 속성(이름, 나이, 취미 …)을 보면 학생 클래스 내에서 따로 정의, 선언할 필요 없이 사람 클래스 내의 속성, 행동들을 물려받아 쓰면 됨.
  • 코드의 양도 줄어들고, 프로그램의 유연성이 높아지는 등 여러가지 이점이 있음.

 

상속 살펴보자

→ C++에서 클래스를 상속하는 것은 아래와 같다. 그저 클래스를 상속시키려면 상속받을 클래스의 이름 옆에 :와 접근 제한자, 그리고 상속할 클래스의 이름을 붙여주면 됨.

..
class 클래스명 {
   // ..
}
class 클래스명 : 접근제한자 클래스명
{
   // ..
}
..

 

→ 접근 제한자는 public, private, protected가 들어가게 됨.

상속을 구현해보자

#include <iostream>

using namespace std;

class Human {
private:
	int age;
	char name[10];
	char hobby[20];
public:
	Human(int _age, char * _name, char * _hobby) : age(_age)
	{
		strcpy(name, _name);
		strcpy(hobby, _hobby);
	}
	void getup()
	{
		cout << "기상!" << endl;
	}
	void sleep()
	{
		cout << "취침!" << endl;
	}
	void eat()
	{
		cout << "식사!" << endl;
	}
	void study()
	{
		cout << "공부!" << endl;
	}
	void showInfo()
	{
		cout << "이름: " << name << endl;
		cout << "나이: " << age << endl;
		cout << "취미: " << hobby << endl;
	}
};

class Student : public Human {
private:
	char school[30];
public:
	Student(int _age, char * _name, char * _hobby, char * _school) : Human(_age, _name, _hobby)
	{
		strcpy(school, _school);
	}
	void schoolInfo()
	{
		showInfo();
		cout << "소속 학교: " << school << endl;
	}
};

int main()
{
	Student stu(18, "김철수", "프로그래밍", "자바고등학교");

	stu.schoolInfo();
	stu.getup();
	stu.eat();
	stu.study();
	stu.sleep();

	return 0;
}

결과

 

💡

이름: 김철수

나이: 18

취미: 프로그래밍

소속 학교: 자바고등학교

기상!

식사!

공부!

취침!

 

private, protected, public 상속

  • private는 외부에서 접근이 불가능하며, protected는 외부에서 접근이 불가능 하나 파생 클래스에서는 접근이 가능하고, public는 어디서나 접근이 가능함.

private 상속을 보자

#include <iostream>

using namespace std;

class Parent
{
private:
	int num1;
public:
	int num2;
protected:
	int num3;
};

class Base : private Parent { };
int main()
{
	Base base;

	cout << base.num1 << endl; // error!
	cout << base.num2 << endl; // error!
	cout << base.num3 << endl; // error!
	return 0;
}

 

 

값을 들고오는 코드도 보자

#include <iostream>

using namespace std;

class Parent
{
private:
	int num1;
public:
	int num2;
protected:
	int num3;
};

class Base : private Parent 
{
public:
	Base()
	{
		num2 = 1;
		num3 = 2;
		cout << this->num2 << endl; // error!
		cout << this->num3 << endl; // error!
	};

	int getNum2()
	{
		return num2;
	};

	int getNum3()
	{
		return num3;
	};
};

int main()
{
	Base base;

	cout << base.getNum2() << endl; // error!
	cout << base.getNum3() << endl; // error!
	return 0;
}

 

 

중요한 것은!!

  • 값을 함수로 통해 접근은 할 수 있지만 바로 접근하지 못 한다는 것 왜? 전부 private이기 때문.
  • private 상속을 하게 되면 private 제한자보다 접근 범위가 넓은 멤버는 모두 private 제한자로 바꾸어 상속하는 것이기 때문. 즉 private보다 접근 범위가 넓은 (public, protected) 멤버들은 모조리 private로 바꾸어서 넘어가는 것임.

protected 상속

#include <iostream>

using namespace std;

class Parent
{
private:
	int num1;
public:
	int num2;
protected:
	int num3;
};

class Base : protected Parent { };
int main()
{
	Base base;

	cout << base.num1 << endl; // error!
	cout << base.num2 << endl; // error!
	cout << base.num3 << endl; // error!
	return 0;
}

 

결과

protected상속.cpp:20:10: error: cannot cast 'Base' to its protected base
      class 'Parent'
        cout << base.num1 << endl; // error!
                ^
protected상속.cpp:15:14: note: declared protected here
class Base : protected Parent { };
             ^~~~~~~~~~~~~~~~
protected상속.cpp:20:15: error: 'num1' is a private member of 'Parent'
        cout << base.num1 << endl; // error!
                     ^
protected상속.cpp:8:6: note: declared private here
        int num1;
            ^
protected상속.cpp:21:10: error: cannot cast 'Base' to its protected base
      class 'Parent'
        cout << base.num2 << endl; // error!
                ^
protected상속.cpp:15:14: note: declared protected here
class Base : protected Parent { };
             ^~~~~~~~~~~~~~~~
protected상속.cpp:21:15: error: 'num2' is a protected member of 'Parent'
        cout << base.num2 << endl; // error!
                     ^
protected상속.cpp:15:14: note: constrained by protected inheritance here
class Base : protected Parent { };
             ^~~~~~~~~~~~~~~~
protected상속.cpp:10:6: note: member is declared here
        int num2;
            ^
protected상속.cpp:22:10: error: cannot cast 'Base' to its protected base
      class 'Parent'
        cout << base.num3 << endl; // error!
                ^
protected상속.cpp:15:14: note: declared protected here
class Base : protected Parent { };
             ^~~~~~~~~~~~~~~~
protected상속.cpp:22:15: error: 'num3' is a protected member of 'Parent'
        cout << base.num3 << endl; // error!
                     ^
protected상속.cpp:12:6: note: declared protected here
        int num3;
            ^
6 errors generated.

 

 

값을 들고오는 코드

  • 보면 알 수 있듯이, Base 클래스에서 num2, num3는 바로 값을 넣을 수 있다
  • private은 접근하지 못 한다.
#include <iostream>

using namespace std;

class Parent
{
private:
	int num1;
public:
	int num2;
protected:
	int num3;
};

class Base : protected Parent 
{
public:
	Base()
	{
		num2 = 1;
		num3 = 2;
		cout << this->num2 << endl; // error!
		cout << this->num3 << endl; // error!
	// cout << base.num3 << endl; // error!
	};

	int getNum3()
	{
		return num3;
	};
};

int main()
{
	Base base;

	// base.num2 = 2;
	// // base.num3 = 3;
	// //cout << base.num1 << endl; // error!
	// cout << base.num2 << endl; // error!
	cout << base.getNum3() << endl; // error!
	return 0;
}

 

 

public 상속

  • 다른 곳에서 바로 접근이 가능하지만 protected와 private은 불가능.
#include <iostream>

using namespace std;

class Parent
{
private:
	int num1;
public:
	int num2;
protected:
	int num3;
};

class Base : public Parent { };
int main()
{
	Base base;

	cout << base.num1 << endl; // error!
	cout << base.num2 << endl; // ok!
	cout << base.num3 << endl; // error!
	return 0;
}
jaeyojun@c2r10s3 상속 % c++ public상속.cpp 
public상속.cpp:20:15: error: 'num1' is a private member of 'Parent'
        cout << base.num1 << endl; // error!
                     ^
public상속.cpp:8:6: note: declared private here
        int num1;
            ^
public상속.cpp:22:15: error: 'num3' is a protected member of 'Parent'
        cout << base.num3 << endl; // error!
                     ^
public상속.cpp:12:6: note: declared protected here
        int num3;
            ^
2 errors generated.

 

값을 넣어보는 코드

  • 클래스에서 protected는 접근할 수 있지만 private은 접근 불가능
#include <iostream>

using namespace std;

class Parent
{
private:
	int num1;
public:
	int num2;
protected:
	int num3;
};

class Base : public Parent {

public:
	Base(){
		num2 = 2;
		num3 = 1;
		cout << num3 << endl; // ok!
	}
 };
int main()
{
	Base base;

	//cout << base.num1 << endl; // error!
	cout << base.num2 << endl; // ok!
	//cout << base.num3 << endl; // error!
	return 0;
}

 

 

이 분의 블로그 토대로 공부하였습니다.

C++ 강좌 12편. 상속(Inheritance)

 

C++ 강좌 12편. 상속(Inheritance)

1. 상속(Inheritance)이란? 여러분이 알고계시는 '상속(Inheritance)'은 무엇인가요? 물론, 이미 타 언어에서 상속을 미리 만나보신 분들도 있겠지만, 아닌 분들도 계실겁니다. 상속은 "일정한 친족적 관

blog.hexabrain.net

 

반응형

'C++ > C++ 상속' 카테고리의 다른 글

C++ 상속 오버라이딩  (1) 2024.01.24