2016-07-29 4 views
8
  • C++ 11에서 override specifier은 (서명이 일치하지 않기 때문에) 의도 한 가상 기본 기능을 재정의하지 않도록 보호합니다.
  • final specifier은 의도하지 않게 파생 클래스의 함수를 재정의하는 것을 방지합니다.

=> 지정자 알 수없는 기본 기능을 무시로부터 보호 (아마도 first 또는 no_override 같은)이 있습니까?C++`override` /`final` 지정자의 반대는 무엇입니까?

가상 함수가 파생 클래스의 기존 가상 함수와 같은 서명을 가진 기본 클래스에 추가 된 경우 컴파일러 오류가 발생합니다.


EDIT 4 : 여기, 관련 간단한 답변이 질문을 계속하려면 다시

  • 추상화

    원래 의사 코드 class B : Aprivate: virtual void fooHasBeenDone() = 0;

  • class C : B 구현을 가지고 private: virtual void fooHasBeenDone() override { react(); }
  • 지금 class A 새로운 것을 얻습니다. private: virtual void fooHasBeenDone();
  • 그러나 새 A::foo은 원래 B::foo과 다를 수 있습니다.

구체적인 예 A PainterPath

  • class C : B을 meaing

    • 추상적 인 class B : Avirtual void showPath() = 0; 지금 virtual void showPath() override { mPath.setVisible(); }
    • class A 파일 경로
    • 을 의미하는 새로운 virtual void showPath();를 얻을 구현
    • A가 showPath()를 호출하면 B는 일부 파일 경로 대신 painterPath를 표시합니다.

    은 물론 이것은 잘못된 것입니다, 나는 다음 B::showPainterPath()B::showPath()의 이름을 바꿀뿐만 아니라 B::showPath() override를 구현해야합니다. 나는 컴파일러로부터 정보를 얻고 싶다.

    #include <iostream> 
    #define A_WITH_SHOWPATH 
    
    class A 
    { 
    #ifdef A_WITH_SHOWPATH 
    public: 
        void setPath(std::string const &filepath) { 
         std::cout << "File path set to '" << filepath << "'. Display it:\n"; 
         showPath(); 
        } 
        // to be called from outside, supposed to display file path 
        virtual void showPath() { 
         std::cout << "Displaying not implemented.\n"; 
        } 
    #else 
        // has no showPath() function 
    #endif 
    }; 
    
    class B : public A 
    { 
    public: 
        virtual void showPath() = 0; // to be called from outside 
    }; 
    
    class C1 : public B { 
    public: 
        virtual void showPath() override { 
         std::cout << "C1 showing painter path as graphic\n"; 
        } 
    }; 
    
    class C2 : public B { 
    public: 
        virtual void showPath() override { 
         std::cout << "C2 showing painter path as widget\n"; 
        } 
    }; 
    
    
    int main() { 
        B* b1 = new C1(); 
        B* b2 = new C2(); 
    
        std::cout << "Should say 'C1 showing painter path as graphic':\n"; 
        b1->showPath(); 
        std::cout << "---------------------------\n"; 
        std::cout << "Should say 'C2 showing painter path as widget':\n"; 
        b2->showPath(); 
        std::cout << "---------------------------\n"; 
    
    #ifdef A_WITH_SHOWPATH 
        std::cout << "Should give compiler warning\n or say \"File path set to 'Test'. Display it:\"\n and \"Displaying not implemented.\",\n but not \"C1 showing painter path as graphic\":\n"; 
        b1->setPath("Test"); 
        std::cout << "# Calling setPath(\"Test\") on a B pointer now also displays the\n# PainterPath, which is not the intended behavior.\n"; 
        std::cout << "# The setPath() function in B should be marked to never override\n# any function from the base class.\n"; 
        std::cout << "---------------------------\n"; 
    #endif 
        return 0; 
    } 
    

    실행을 텍스트 출력을 보면 다음과 같습니다


    는 컴파일 실제 예를이다.참고로


    , 특정 사용 케이스 (PainterPath 인스턴스)와 이전 예 :

  • +3

    아마도'-Wsuggest-override' GCC 옵션이 도움이 될 수도 있습니다. https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html – gavv

    +0

    @gavv 그게 제가 찾고있는 것입니다. 플랫폼 독립적 인 방법이 있습니까? VS2012에서도 필요합니다. –

    +1

    IMHO 이것은 디자인에 관한 질문입니다. Bathsheba가 언급했듯이, 기본 클래스에서 final을 사용할 때를 제외하고는 가능하지 않습니다. 또는 Leon이 언급 한 트릭을 사용할 수 있습니다. 인터페이스 클래스 목적을 위반하고 (http://coliru.stacked-crooked.com/a/17346a88fa6aaa89) 여기에 다른 문제가 있습니다. 마지막 편집에서 언급했듯이 함수의 이름을 다른 의미로 지정하면 안됩니다. 만약 당신이 정보를 얻으려면 몇 가지 분석 도구 (또한 Bathsheba imho가 여기에서 유일한 정답을 언급 함)를 사용하십시오. (IMHO) – user1810087

    답변

    관련 문제