林's

[C++] 상속의 접근제한자 본문

프로그래밍/현대적 C++ 프로그래밍

[C++] 상속의 접근제한자

풀림이 2019. 4. 6. 22:22

참고글(영어): 클릭!

 

우선 혼란을 피하기 위해 두 용어를 정리하고 가겠습니다.

 

1). Access Modifier 와 Access Specifier

-access specifier (접근지정자): public, protected, default, private 와 같은 키워드로

클래스 혹은 변수명 앞에 붙여서, 외부로부터 이 친구에게 접근할 수 있는 범위를 제한시키는 용도로 쓰입니다.

그래서 '접근 제한자'라고 불리우기도 한답니다.

 

접근지정자는 특히, public protect int a = 0;과 같이 한 번에 여러개를 쓸 수 없이 하나만 써야한다는 특징이 있습니다.

 

-access modifier (접근제어자): final, static, abstract, const, volatile 과 같은 키워드로

접근지정자와 달리 public static final 처럼 여러개가 동시에 올 수도 있으며,

변수나 함수 등을 특별한 형태로 동작시키기 위한 용도로 쓰입니다. 

 

 

※ 그러나 실생활에서는 이처럼 구분하지 않고 접근지정자(Access Specifier)로 한 번에 부르고 있는 것 같습니다.

하지만 원문에서 알 수 있듯이 이 둘은 의미가 서로 다르다는 점을 알고 가셨으면 좋겠습니다.

 

 

2). public 상속

- class Derived : public Child

 가장 많이 쓰이는 상속으로, 외부에서 Derived 객체의 멤버를 사용할 때, 부모객체인 Child의 멤버중 public에 접근할 수 있게 하기 위한 용도로 사용됩니다. 그래서 특별한 경우가 아니면 이 방식을 가장 많이 사용됩니다.

그리고 언제나 그렇듯, 자식 클래스에서는 부모클래스의 멤버중 자기자신만 접근가능한 private 이외의 모든 멤버에 접근이 가능합니다. 

 

그리고 자바에 익숙하신 분들은 특히나, 

class Derived : Child 

와 같이 상속접근지정자를 생략하는 것이 마치 아래의

class Derived : public Child

와 같은 같은 것이라고 으레 짐작할 수 있겠습니다만,

 

사실

클래스 내부에서 접근 제한자를 붙이지 않았을 경우

class Derived : private Child 로 컴파일이 됩니다!!

 

이는 마치 아래와 같이

class Child

{

    int default_is_private;

};

멤버변수에 접근지정자를 붙이지 않으면 기본적으로 private로 컴파일 되는 것과 같은 이치입니다.

 

 

2). private 상속

 

private 상속은 자식클래스에서 부모의 private 멤버에 접근하는 것조차 불가능합니다.

protected 나 public 상속은 자식객체 안에서는 private 처럼 동작을 합니다. 그래서 자식’클래스의 선언부''에서는 .을 통해 부모객체의 멤버에 접근할 수 있지만 다시말하지만, main 함수 같은 클래스 밖에서는 '.'을 통해 부모객체에 대한 접근은 허용되지 않습니다. 

 

 

3). protected 상속

class Derived : protected Child

도 거의 쓰이지 않습니다. protected 의 일반 성질과 같이 자식 클래스에서 부모 클래스의 멤버를 접근하고자 할 때 사용합니다. 자식 클래스에서 부모 클래스의 protected 멤버에 당연히 접근할 수 있습니다.

그리고  그리 클래스 선언부 바깥인 main() 함수같은 곳에서 protected 상속을 받은 자식 클래스의 객체에 쩜을 붙여서 부모 클래스의 protected 멤버에 접근할 수 없습니다. 이부분이 헷갈리시거나 납득이 안 되시는 분들은 아래의 주의할점을 읽어보시면 이해가 될 것입니다.

(이 경우, 부모의 private 멤버는 당연히 접근할 수 없겠죠?)

 

 

주의할점).

main() 함수처럼 클래스 정의 코드블럭 바깥에서 Derived 객체를 만들어 사용할 때!,

부모클래스인 Child의 멤버중 protected인 멤버에 접근을 하려고 하면 접근이 안 되는 현상을 확인할 수 있을 것입니다.

 

아니, protected는 상속받은 객체에 한해서 언제 어디서나 접근이 가능한게 아닌가요? 저또한 그랬으며 공부를 하기전까지는 왜 안 되는지 몰랐는데.

 

사실 protected 여러분이 아는 상식에서 한가지 제약조건이 더 들어갑니다. 바로

 

클래스 선언 블록 안! 에서만 접근이 가능하다는 것입니다!

즉, 외부에서는 접근이 불가능하다는 소리죠!

 

다시 말해서 아래의 예제와 같이,

class Child

{

    protected int a;

}

class Derived : public Child

{

           ....  

           ....

}; <<=== 이 클래스 정의 블럭을 지나는 순간,

main()

{

    Derived d;

    d.a = 10; 

}

외부에서는 접근이 불가능하다는 사실! 반드시 기억해주세요!

 

 

이상으로 상속의 접근제한자에 대해 알아보았습니다. 궁금하시거나 토의하고 싶은 이야기가 있다면 언제든지 댓글로 말씀해주세요 ^^

감사합니다.

Comments