-
Effective C++...31일지 2022. 8. 2. 08:40
상속된 이름을 숨기는 일은 피하자
C++의 유효 범위 탐색 과정과 문제
만약 프로그램 실행 중 특정 함수가 발견됐다면 해당 함수를 찾기 위해 컴파일러는 다음의 과정을 밟게 된다.
- 지역의 유효 범위 탐색
- Derived 클래스의 유효 범위 탐색
- Base 클래스의 유효 범위 탐색
- 네임 스페이가 있으면 네임 스페이스 내부 범위 탐색
- 전역 유효범위 탐색
이 과정에서 Base 클래스에 존재하는 함수와 동일한 이름의 함수를 Derived 클래스에서 생성했다면 함수의 매개 변수가 다르거나 비가상 함수라고 하더라도 Base 클래스의 함수의 이름이 가려지게 된다.
class Base {private:
int x;public: virtual void mf1() = 0;virtual void mf1(int);
virtual void mf2(); void mf3();
void mf3(double);
...};class Derived: public Base {public:
virtual void mf1();
void mf3();
void mf4(); ...};
Derived d;int x;...d.mf1(); // Derived의 mf1 호출d.mf1(x); // 에러, Base::mf1이 가려짐
d.mf2();
d.mf3(); // Derived의 mf3 호출d.mf3(x); // 에러, Base::mf3이 가려짐
이름 가리기 문제 해결 방법
이러한 문제를 해결하는 방법은 Derived 클래스에서 Base 클래스의 함수를 사용한다는 것을 using으로 선언해주는 것이다.
class Derived: public Base {
public:
using Base::mf1;
using Base::mf3;
virtual void mf1();
void mf3();
void mf4();
...};
Derived d;
int x;
...
d.mf1(); // Derived의 mf1 호출
d.mf1(x); // Base의 mf1 호출
d.mf2();
d.mf3(); // Derived의 mf3 호출
d.mf3(x); // Base의 mf3 호출
그런데 상속받은 함수 중 하나의 함수만 상속받고 싶을 때는 using은 이름 단위로 처리를 하기 때문에 using으로는 처리가 불가능하다.
따라서 이런 경우에는 전달 함수를 사용해 처리할 수 있다.
class Derived: private Base {
public:
virtual void mf1()
{
Base::mf1();
}
...
};