C++

이름 숨김

춤추는수달 2024. 4. 15. 14:31

 

이름 숨김이란, 어떤 멤버 A가 있을 때, 중첩된 선언 영역 혹은 파생 클래스에서 같은 이름의 멤버를 선언할 경우, 멤버 A가 무시되는 규칙입니다.

https://www.ibm.com/docs/en/i/7.5?topic=scope-name-hiding-c-only

 

Name hiding (C++ only)

If a class name or enumeration name is in scope and not hidden, it is visible. A class name or enumeration name can be hidden by an explicit declaration of that same name — as an object, function, or enumerator — in a nested declarative region or deriv

www.ibm.com

위의 링크에 나온 예를 보겠습니다.

#include <iostream>
#include <typeinfo>
using namespace std;

namespace A {
  char x;
};

namespace B {
  using namespace A;
  int x;
};

int main() {
  cout << typeid(B::x).name() << endl;
}

namespace A와 B에서 모두 x라는 이름의 변수를 선언했습니다. 

그런데 B에서는 A를 사용하도록 using namespace A; 구문을 사용했습니다.

이럴 경우 B::x는 char가 아닌 int형이 됩니다. 즉, char x는 무시됩니다.

이런 경우는 납득되는 편입니다만, 잘 납득되지 않는 경우도 있습니다. 상속되는 클래스들 사이의 멤버 함수의 경우 그렇습니다.

 

C++의 상속 관계에 있는 클래스들 사이에도 '이름 숨김' 규칙이 적용됩니다.

자식 클래스에서 부모 클래스에 있는 멤버와 같은 이름의 멤버를 정의하면, 부모 클래스의 멤버는 무시됩니다. 비록 함수의 시그니처(매개변수, 반환 타입)가 다를지라도요.

이번에도 예를 들어보겠습니다.

class ParentClass {
public: 
     virtual void someFunc(int a){
        printf(" ParentClass :: someFunc (int) \n");
    };

    virtual void someFunc(int* a){
        printf(" ParentClass :: someFunc (int*) \n");
    };
};

class ChildClass : public ParentClass {
public:
    virtual void someFunc(int* a){
        printf(" ChildClass ::  someFunc(int*) \n");
    };
};

int main(){
    ChildClass obj;
    /* This function call results in an error: */
    obj.someFunc(7);
}

위의 코드에서 obj.someFunc(7); 문장은 대충 이런 형태의 함수는 없다는 뜻의 컴파일 에러가 발생됩니다. ParentClass의 void someFunc(int a)를 아예 인식도 못하고 있습니다. 

우리의 생각대로라면, ChildClass에서 ParentClass를 잘 상속 받았고, someFunc(int*)와 someFunc(int)의 시그니처가 다르니 ParentClass의 someFunc(int)를 못찾을리 없을 것입니다.

그러나 C++의 이름 숨김 규칙에 의해 ParentClass의 someFunc는 가려졌습니다. ChildClass에 같은 이름의 함수가 선언되었기 때문입니다.

오버라이딩이 일어날 상황도 아닙니다. someFunc(int*)와 someFunc(int)의 시그니처가 다르니까요.

오버로딩도 일어나지 않았습니다. ChildClass::someFunc(int*)와 ParentClass::someFunc(int)는 같은 공간에 선언되지 않았으니까요.

그저 이름 숨김이 일어난 것입니다.

이를 잘 설명해주는 글을 찾았는데요, 아래 링크를 확인해 주세요.

https://www.programmerinterview.com/c-cplusplus/c-name-hiding/

 

이 글에서 말하길, 이런 규칙을 만든 이유는 C++표준 개발자들은 부모 클래스에 호출되는 함수와 자식 클래스로 내려갔을 때 호출되는 함수가 다른 것은 바람직하지 않다고 생각해서 그랬다네요.

 

'C++' 카테고리의 다른 글

우측값 참조와 이동연산  (0) 2024.05.02
RTTI  (0) 2024.04.27
가상함수  (2) 2024.04.12
헷갈리는 C++ 질문들  (0) 2024.04.12
Casting (Static, Dynamic, Reinterpret )  (0) 2023.03.28