다음과 같은 간단한 코드에서 시작해 보자. 순수 가상 클래스인 Base에 Bark란 메소드가 있고, 그걸 상속 받은 순수 가상 클래스인 Derived는 BarkN을 가지고 있다. 이를 상속 받은 Dog은 두 메소드를 구현한다. main에서는 Dog를 할당해서 Derived 포인터를 통해서 Bark와 BarkN을 호출하고 있다. 아무 문제 없는 코드다.
#include <stdio.h>
class Base
{
public:
virtual void Bark() = 0;
};
class Derived : public Base
{
public:
virtual void BarkN(int n) = 0;
};
class Dog : public Derived
{
public:
virtual void Bark() { printf("Dog Bark\n");
}
virtual void BarkN(int n)
{
for (int i = 0; i < n; ++i)
printf("Dog Bark\n");
}
};
int
main()
{
Derived *dog = new Dog;
dog->Bark();
dog->BarkN(5);
}
우리는 C++에서 함수를 오버로딩할 수 있다는 것을 알고 있다. 그래서 굳이 BarkN으로 이름을 지을 필요가 없다는 것을 깨달았다. N을 제거하고 다음처럼 Bark로 코드를 고쳐보자. 이제는 컴파일이 되지 않는다. dog->Bark(); 호출하는 부분에서 그런 함수를 찾을 수 없다고 오류가 발생하는 것이다. 이는 상속 받은 클래스에서 함수를 오버로딩하면 상위 클래스의 메소드가 숨겨지는 문제 때문이다.
#include <stdio.h>
class Base
{
public:
virtual void Bark() = 0;
};
class Derived : public Base
{
public:
virtual void Bark(int n) = 0;
};
class Dog : public Derived
{
public:
virtual void Bark() { printf("Dog Bark\n");
}
virtual void Bark(int n)
{
for (int i = 0; i < n; ++i)
printf("Dog Bark\n");
}
};
int
main()
{
Derived *dog = new Dog;
dog->Bark();
dog->Bark(5);
}
문제를 해결하기 위해서는 아래 코드처럼 Derived 클래스에서 상위 클래스의 메소드를 사용하겠다는 것을 명시적으로 표시해주면 된다.
class Derived : public Base
{
public:
using Base::Bark;
virtual void Bark(int n) = 0;
};