C++ 상속(inheritance)

Joosi_Cool·2022년 10월 14일
2

C++

목록 보기
18/20
post-thumbnail

상속이란?

상속은 기존 클래스의 특성(데이터 멤버, 멤버 함수) 를 가져와서 새로운 클래스로 만드는 것이다. 새로운 클래스는 다른 특성도 포함해서 만들 수 있다.
1. 기존 클래스 => 부모 클래스
2. 새로운 클래스 => 자식 클래스

추가적으로 한단계로 이루어진 부모 자식관계를 직접 상속 관계라 한다.
또한 두단계 이상으로 이루어진 관계는 간접 상속 관계라 한다.

한 자식이 여러 부모의 클래스에서 상속 받는 것이 가능한데, 이는 C++만 가능하다.(다중 상속 허용 가능)




접근 제한자?

우선, 상속에 대해 알기 전에 접근 제한자에 대해 알아보는 것이 좋다.

  1. private => 오직 클래스 안에서만 접근 가능하다. 예를 들어서, 상속을 통해서 부모 클래스의 private 변수를 가져오고 싶다면 부모 클래스에서 get함수를 통해 가져와야한다.

  2. protected => 자신을 상속하는 클래스까지만 접근 가능.
    외부에서는 접근이 안되지만, 상속되어지는 자식 클래스에서는 이를 사용 가능하다. 따라서, 부모 클래스에서 private로 선언되어 있는 멤버 변수를 protected 로 바꾼다면 get함수를 사용하지 않더라도 바로 사용 가능하다.

  3. public => 어떤 클래서에서든 접근 가능하다.


상속 사용 방법

자식 클래스 : 접근 제한자 부모 클래스
{
자식 클래스 내용
}

방법은 이러한데, 여기서 중요한 점은 접근 제한자 부분이다. 상속을 할 때, 어떠한 접근 제한자를 쓰는냐에 따라서 사용 범위가 정해진다.

접근 순위

  1. public > 2. protected > 3. private
  1. 만약 private 로 상속을 받는다면, 아래와 같이 축소된다.
  • private => private
  • protected => private
  • public => private
  1. 만약 protected 로 상속을 받는다면, 아래와 같이 축소된다.
  • private => private
  • protected => protected
  • public => protected
  1. 만약 public 로 상속을 받는다면, 아래와 같이 축소된다.
  • private => private
  • protected => protected
  • public => public



1. 예시코드(public)

#include<iostream>
using namespace std;

class A {
private:
	int a{1};
	
protected:
	int b{2};

public:
	int c{3};
};

class B :public A {
	void showB() {
		//성공 => protected는 자식에서 사용 가능
		cout << b << endl;
	}
};




int main() {

	B example;
	//오류 (private 변수)
	cout << example.a << endl;
	//오류 (proteced 변수)
	cout << example.b << endl;
	//성공 (public 변수)
	cout << example.c << endl;



	return 0;
}

위에 코드의 경우 public으로 받았기 떄문에, 아래와 같이 된다.

  • private => private
  • protected => protected
  • public => public


    따라서 a,b 는 오류가 생긴다. showB()는 protected 변수를 사용할 수 있다.

2. 예시코드(protected)

#include<iostream>
using namespace std;

class A {
private:
	int a{1};
	
protected:
	int b{2};

public:
	int c{3};
};

class B :protected A {
	void showB() {
		//성공 => protected는 자식에서 사용 가능
		cout << b << endl;
	}
};




int main() {

	B example;
	//오류 (private 변수)
	cout << example.a << endl;
	//오류 (proteced 변수)
	cout << example.b << endl;
	//오류 (public 변수)
	cout << example.c << endl;



	return 0;
}

위에 코드의 경우 public으로 받았기 떄문에, 아래와 같이 된다.

  • private => private
  • protected => protected
  • public => protected


    다른 건 1번 코드와 같고, 하나 다른점은 c가 메인함수에서 출력이 안된다는 점이다. 이는 protected를 통해 상속을 받아서, public 변수가 protected로 축소된 것이다.

3. 예시코드

#include<iostream>
using namespace std;

class A {
private:
	int a{1};
	
protected:
	int b{2};

public:
	int c{3};
};

class B :private A {
public:
	void showB() {
		//성공 => 아래 추가 설명
		cout << b << endl;
	}
};


int main() {

	B example;
	example.showB();

	return 0;
}

위에 코드의 경우 public으로 받았기 떄문에, 아래와 같이 된다.

  • private => private
  • protected => protected
  • public => public


    여기서 주의해야 될점은 protected가 private 으로 축소 되었다면 자식 클래스에서 멤버 함수에서 부모클래스의 멤버 변수를 사용 못하는 것이 아니냐는 의문이 있을 수 있다.
    하지만, 자식 클래스에선 private로 상속되었다고 해서, 바로 자식 클래스 안에서 private로 바뀌는 것이 아니다.
    이 자식 클래스를 사용할때, 그 변수들이 private로 바뀌는 것이다.


    따라서 자식 클래스 선언에선 부모 클래스에서의 제한자를 따르며, 이후에 자식 클래스를 사용할때, 선언해준 제한자를 따른다고 정리하면 될 것 같다.



부모 클래스 private 변수 접근 방법

부모 클래스에서의 변수를 자식 클래스에서 바로 받을 순 없다. 아래 코드와 같이 진행할 경우, 접근할 수 없다고 나오며 오류를 발생하게 된다.

#include<iostream>
using namespace std;

class A {
private:
	int a{ 1 };
	int b{ 2 };
	int c{ 3 };
	
public:
	void showAdd() {
		cout << a << endl << b << endl << c << endl;
	}
};

class B :public A {

public:
	void showA() {
    //오류 => a를 접근할 수 없음.
		cout << a << endl;
	}
};



그렇다면 어떻게 접근해야 할까? 두가지 방법이 있다.

1. 변수 get 함수 생성

#include<iostream>
using namespace std;

class A {
private:
	int a{ 1 };
	int b{ 2 };
	int c{ 3 };
	
public:
	//get함수를 통해 private변수 접근
	int getA() { return a; }
	void showAdd() {
		cout << a << endl << b << endl << c << endl;
	}
};

class B :public A {

public:
	void showA() {
		cout << getA() << endl;
	}
};

2. private -> protected로 변경

두번째 방법은 멤버변수를 protected로 바꾸어주는 것이다.
그렇게 함으로써 자식 클래스에서 사용 가능하게 해준다.

#include<iostream>
using namespace std;

class A {
//protected로 선언하면서 자식에서 사용 가능하게 한다.
protected:
	int a{ 1 };
	int b{ 2 };
	int c{ 3 };
	
public:
	void showAdd() {
		cout << a << endl << b << endl << c << endl;
	}
};

class B :public A {

public:
	void showA() {
		cout << a << endl;
	}
};
profile
집돌이 FE개발자의 노트

0개의 댓글