33. Do not Hide Inheritanced name

C++의 이름 가리기 규칙은 클래스에서도 동일하게 적용된다.
class Base{
private:
int x;
public:
virtual void mf1()=0;
virtual void mf2();
void mf3();
// ...
};
class Derived: public Base{
public:
virtual void mf1();
void mf4();
// ...
};
void Drived::mf4(){
// ...
mf2();
// ...
}
클래스에서 함수를 찾을 때(위에서 mf2()를 수행할 때),
가장 먼저 해당 스코프에서 함수를 찾고(위에서 Derived::mf4),
그 다음 해당 클래스에서 함수를 찾는다(위에서 Derived class)
이 후, 상속한 클래스에서 함수를 찾고(위에서 Base class)
마지막에 전역 유효범위에서 찾는다.
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); // error Base::mf1(int)가 Derived::mf1에 가려 호출되지 않음
d.mf2(); // Base::mf2
d.mf3(); // Derived::mf3()
d.mf3(x); // error Base::mf3(double)가 Derived::mf3에 가려 호출되지 않음
이름가리기는 기본 클래스와 파생 클래스에 있는 함수들이 받아들이는
매개변수 타입을 구분하지 않는다.
함수가 가상함수인지 비가상함수인지의 여부에도 상관없이 이름을 가림

가려진 이름을 사용하기 위해서 using 선언을 사용한다.
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:
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(int)
d.mf2(); // Base::mf2
d.mf3(); // Derived::mf3
d.mf3(x); // Base::mf3(double)
private 상속
private 상속을한 경우,
using 선언을 사용할 수 없다.(using 선언시 모든 함수가 파생 클래스로 내려감, private 상속한 이유가 없음)

전달함수(forwarding function)을 사용할 것
class Base{
public:
virtual void mf1()=0;
virtual void mf1(int);
// ...
};
class Derived: private Base{
public:
virtual void mf1(){ // 전달함수, 컴파일러가 암묵적으로 인라인 시킴
Base::mf1();
}
// ...
};
// ...
Derived d;
int x;
d.mf1(); // Derived::mf1 호출, Derived::mf1은 Base::mf1()을 호출함
d.mf1(x); // error Base::mf1(int)가 가려져 있음