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에 해당하는 키워드는 너무 불편한 방법으로 우회해야 한다 – 좀 더 간편한 클래스 설계를 할 수 있게 된다. 그렇지만 호환성 문제는…

Jinuk Kim
Jinuk Kim

SW Engineer / gamer / bookworm / atheist / feminist

Articles: 935

6 Comments

  1. 저도 다른 분 코드를 보다가 되나 싶어서 매뉴얼을 들여다봤는데 몇 개는 native C++ 에서도 되는 거더라구요;;

  2. override는 꽤 맘에 들었던 기능인데 (base의 signature가 바뀔 때 삽질할 확률 감소(…)), for each는 상당부분 C++ 자체 문법에서도 가능하다고 생각해서 사용을 자제(?) 중

Leave a Reply