Skip to content

2014 06 17 override 키워드, 메서드 오버라이딩

krikit edited this page Nov 26, 2014 · 1 revision

override 키워드

아래와 같이 자식 클래스에서 부모 클래스의 메서드를 오버라이딩한 경우를 생각해 봅시다.

class Parent {
 public:
  virtual void foo(int i);
};

class Child {
 public:
  virtual void foo(int i);
};

그런데 부모 클래스에서 int를 인자로 받는 foo(int) 메서드의 확장성을 고려해 foo(double)로 변경해 버리면 자식 클래스에서 오버라이딩해줬던 foo(int) 메서드는 오버라이딩이 아니라 새로운 메서드가 되지요. 이러한 상황을 방지하기 위해 C++11에서는 오버라이딩 상황이 아니면 오류를 내도록 하는 override 키워드가 생겼습니다.

class Parent {
 public:
  virtual void foo(double d);    // 수정
};

class Child {
 public:
  virtual void foo(int i) override;    // 오류 발생
};

static 메서드의 오버라이딩

C++에서는 static 메서드는 오버라이딩 되지 않습니다. static 메서드의 경우 dynamic(run time) 바인딩이 아니라 static(compile time) 바인딩이 일어나기 때문입니다.

class Parent {
 public:
  static int foo() { return 0; }
};

class Child : public Parent {
 public:
  static int foo() { return 1; }
};

int main(int argc, char** argv) {
  Child child;
  Parent& ref = child;
  child.foo();    // 1
  ref.foo();    // 0

  return 0;
}

디폴트 인자값을 갖는 메서드의 오버라이딩

디폴트 인자의 값을 결정할 때에는 객체가 아니라 타입만으로 결정을 합니다. 그럼에도 메서드의 바디는 오버라이딩된 메서드가 호출됩니다. 그래서 의도하지 않은 결과가 나올 수 있는데요. 아래 코드를 보시죠.

class Parent {
 public:
  virtual int foo(int i = 0) { return i; }
};

class Child : public Parent {
 public:
  virtual int foo(int i = 1) { return i + 10; }
};

int main(int argc, char** argv) {
  Child child;
  Parent& ref = child;
  child.foo();    // 11
  ref.foo();    // 10

  return 0;
}

그래서 디폴트 인자를 갖는 메서드를 오버라이딩할 경우 디폴트 인자의 값을 똑같이 지정해 주는 것이 좋습니다.

Clone this wiki locally