C++을 위한 MS VC++확장 키워드 몇 가지

작년 9월에 C++에서 상속받을 수 없게 만든 class (=Java의 final class 류)에 관한 글을 소개했었다 – 상당히 불편한 방법으로 final 키워드 기능을 흉내낸다.

오늘 회사에서 (다른 팀이) 이전에 작성한 코드를 보다가, final keyword에 해당하는 MS VC++ 확장 키워드를 발견했다. MS VC++에서는 class의 상속에 관련되서 몇 가지 추가된 키워드를 가지고 있다.

  • abstract – 추상 클래스를 선언할 수 있게 해주는 키워드. 이 클래스의 인스턴스;instance를 만들 수 없게 한다
  • override – 특정 멤버 함수를 선언할 때 해당 선언이 기반;base 클래스의 멤버 함수를 override 한 것일 때만 유효하게 한다
  • sealed – 특정 멤버 함수 혹은 클래스에 대해 해당 함수를 하위 클래스들이 override할 수 없게 막는다.

실제로 사용해보면 – 몇 가지 컴파일 오류를 섞어서 써보면 – 다음과 같은 코드가 나온다.

class Base abstract {
public:
    virtual void foo() = 0;
    virtual void bar() = 0;
};

// error - 'Base': a class declared as 'abstract'
// cannot be instantiated
Base b;

class Derived : public Base
{
public:
    virtual void foo() override { };
    virtual void bar() sealed override { };

    // error - 'Derived::foo2' : method with override
    // specifier 'override' did not override
    // any base class methods
    virtual void foo2() override { };
};

class Derived2 sealed : public Derived
{
public:
    virtual void foo() override { };

    // error - 'Derived::bar': function declared as 'sealed'
    // cannot be overridden by 'Derived2::bar'
    virtual void bar() override { };
};

// error - 'Derived3' : cannot inherit from 'Derived2' as it
// has been declared as 'sealed'
class Derived3 : public Derived2 {
};

각각의 오류는 다음의 의미다. (순서대로)

  • Base 는 abstract class라서 인스턴스를 만들지 못해서 변수 b의 정의는 에러가 된다.
  • Derived에서는 상위 클래스에 없는 멤버 함수인 bar()를 덮어씌우려고;override해서 컴파일 에러를 보게 된다.
  • 그리고 멤버 함수 레벨에서도 사용된 sealed로 인해 특정 가상 함수;virtual function이 더이상 덮어씌워지는 것을 막을 수 있다.
  • 마지막으로 Derived3는 Derived2를 상속받으려 했으나 이 클래스 자체가 sealed라 상속받을 수 없다.

이런 형태로 추가적인 키워드 도입을 통해서 – 특히나 final에 해당하는 키워드는 너무 불편한 방법으로 우회해야 한다 – 좀 더 간편한 클래스 설계를 할 수 있게 된다. 그렇지만 호환성 문제는…