본문 바로가기

전생의 기억/C++

C++. 상속에서 범위연산자 public,private,protected가 가지는 의미

C++에서는 문법 관점에서 보면 (자식)B클래스가 (부모)A클래스를 상속받을 수 있다.


이때에, 상속을 받는 자식클래스(유도,하위 등 명칭이 다양)인 B클래스를

선언할 때에는 다음과 같이 선언한다.


Class B : public A

{

public : ....

B() : A()

{

...

}

private : ....


};


다음과 같이, 

1. 클래스 부분 옆에 :(이니셜라이즈)를 통해 A클래스를 public(or private or protected)

   상속을 선언해준다.


2. 유도 클래스인 B클래스의 생성자 부분에서, :(이니셜라이즈)를 통해 A클래스(부모 클래스)의

   생성자를 호출선언 해준다.


C++에서 어떠한 클래스의 객체가 생성되었냐 안되었냐의 기준은 생성자의 호출이 되어 실행이

완료된 시점을 기준으로 하기때문에, 간단히 글로 B클래스(자식 클래스)의 객체 생성과정을 정리하면,


1. 클래스들의 정보가 메모리 공간 할당된다.

2. 유도(자식)클래스의 생성자가 new연산자를 통해 호출된다.

3. B클래스의 생성자에서 이니셜라이즈를 통하여 부모 클래스의 생성자가 호출된다.

4. 부모클래스의 생성자 구문이 실행되고, 자식 클래스의 생성자가 실행된다.


여기까지가 상속을 받은 B클래스의 객체생성 방식이였고, 간략한 설명을 위해 A클래스와 B클래스 모두 void 생성자를 사용하였다고 가정하였다.


그렇다면, 범위연산자인 public이나, private, protected를 상속에서 사용할 때 무슨 의미를 뜻하는 것일까?

  

한마디로 말하면, B클래스가 A클래스를 상속받음으로서, A클래스의 멤버들을 사용할 수 있게 되는데,

B클래스의 관점에서, A클래스의 멤버들의 [접근범위]를 결정하는 것이 바로 상속의 형태가 되는것이다.


public 상속으로 부모 클래스 A를 상속받는 경우, 이 A클래스에 있는 멤버변수,멤버함수들에게

적용되어있는 접근범위인 public이나 protected의 접근범위를 그대로 유지한다는 뜻이다.

단, 예외적으로 private로 선언된 멤버의 경우, B클래스 멤버에서는 완전히 접근이 불가능하다.


여기서 접근이 불가능하다는 뜻은, A를 상속받은 B클래스의 멤버함수에서는, private로 선언된 A클래스의

멤버변수에 접근이 불가능하다는 뜻이며, 오로지 A클래스의 멤버함수에서만 해당 변수에 접근이 가능하다는 뜻이다.


protected 상속을 받는 경우, protected는 protected로, 그리고 public으로 선언된 멤버변수의 접근범위는

protected로 범위를 결정하겠다는 뜻이다.

물론, private는 접근이 불가능하다.


private 상속을 받는 경우, A클래스의 private 멤버는 마찬가지로 B클래스에서는 접근이 불가능하게 되고,

나머지 protected와 public 멤버들은 private가 된다.

예를 들어, A클래스를 상속받은 B가 있고, A클래스에는 private, protected, public으로 선언된

각각의 멤버변수 num1, num2, num3가 있다고 가정하자.

B클래스의 멤버함수로는 num1Adder(), num2Adder(), num3Adder()라는 함수가 있다고 가정한다.

(이 함수는 num1,num2,num3를 각각 증가시키는 기능)


1. public상속을 받은 경우


B bclass = new B();

B.num1++ //(x) 접근불가

B.num2++ //(o) protected는 같은 클래스 내 또는 상속에 한하여 접근가능

B.num3++ //(o) public은 어디서든 접근 ok

B.num1Adder() //(x) 접근불가

B.num2Adder() //(o) protected는 같은 클래스 내 또는 상속에 한하여 접근가능

B.num3Adder() //(o) public은 어디서든 접근 ok


2. protected상속을 받은 경우


B bclass = new B();

B.num1++ //(x) 접근불가

B.num2++ //(x) protected는 같은 클래스 또는 상속을 받은 클래스의 멤버함수를 통해 접근가능

B.num3++ //(x) protected는 같은 클래스 또는 상속을 받은 클래스의 멤버함수를 통해 접근가능

B.num1Adder() //(x) 접근불가

B.num2Adder() //(o) protected는 같은 클래스 내 또는 상속받은 클래스에 한하여 접근가능

B.num3Adder() //(o) protected는 같은 클래스 내 또는 상속받은 클래스에 한하여 접근가능


3. private상속을 받은 경우


B bclass = new B();

B.num1++ //(x) 접근불가

B.num2++ //(x) private는 같은 클래스 내에서만 접근 가능 (함수를 이용하여 접근가능)

B.num3++ //(x) private는 같은 클래스 내에서만 접근 가능 (함수를 이용하여 접근가능)

B.num1Adder() //(x) 접근불가

B.num2Adder() //(o) private는 같은 클래스 내에서 함수를 통해 접근 가능

B.num3Adder() //(o) private는 같은 클래스 내에서 함수를 통해 접근 가능


거창하게 많은 이야기를 한 것 같지만, 특별한 경우가 아니라면

그냥 public 상속을 사용하는 경우가 대부분이다.


위의 내용이 잘 이해가 되지 않는다면, 접근 범위연산자인 private의 정의를 다시 생각해보는 것도

좋은 방법이라고 생각한다.

----------------------------------------------------------------------------------------------------------

PS. 범위 순서 private< protected < public

private -> 같은 클래스 내의 멤버함수를 통해서 접근이 가능하다.(정보은닉을 위해)

protected -> 같은 클래스 또는 상속을 받은 클래스의 경우에 멤버함수를 통해 접근이 가능하다.

public -> 모든 경우에 접근이 가능하며, 객체를 통해서도 직접 접근 가능