페이지

2015년 1월 4일 일요일

상속된 이름을 숨기는 일은 피하자.

* 파생 클래스의 이름은 기본 클래스의 이름을 가립니다. public 상속에서는 이런 이름 가림 현상은 바람직하지 않습니다.


int x;
void func() {
    double x;
    std::cin >> x;
}



위의 예제를 보면 func() 안에 선언된 double형 x에 값을 집어 넣는다. 유효범위(scope) 검사를 하여 가장 가까운 영역부터 x를 찾으면 더 이상 검색을 하지 않는다. 심지어 data type에 관하여도 모두 무시한다.

 클래스의 상속에서도 마찬가지다. 가장 가까운 곳부터 찾아서 같은 이름을 하나라도 찾아내면 더이상 찾지 않는다. 심지어 parameter가 다르거나 말거나 꺼리낌이 없다. 가상함수인지 비가상함수인지도 상관없이 이름을 가려버린다.


class Base {
private:
  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(); // OK
d.mf1(x); // Error! Derived:mf1이 Base::mf1을 가림

d.mf3(); // OK
d.mf3(x); // Error! Derived:mf3이 Base::mf3을 가림

* 가려진 이름을 다시 볼 수 있게 하는 방법으로, using 선언 혹은 전달 함수(forwarding fucntion)를 쓸 수 있습니다.


class Base {
private:
  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 선언

  virtual void mf1();
  void mf3();
  void mf3(double d) { Base::mf3{d); } // inline 전달함수

  void mf4();
};

Derived d;
int x;

d.mf1(); // OK
d.mf1(x); // OK
d.mf3(); // OK
d.mf3(x); // OK

댓글 없음:

댓글 쓰기