하위 클래스에서 메서드가 재정의되는 것을 방지하는 방법이 있나요?

StackOverflow https://stackoverflow.com/questions/17483

  •  09-06-2019
  •  | 
  •  

문제

자식 클래스가 부모 클래스의 특정 메서드를 오버라이드하는 것을 방지하기 위해 C++의 언어 기능이나 기술을 알고 있는 사람이 있습니까?

class Base {
public:
    bool someGuaranteedResult() { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

가상이 아니더라도 이는 여전히 허용됩니다(적어도 제가 사용하는 Metrowerks 컴파일러에서는). 여러분이 얻는 것은 비가상 상속 함수 X를 숨기는 것에 대한 컴파일 시간 경고뿐입니다.

도움이 되었습니까?

해결책

몇 가지 아이디어:

  1. 함수를 비공개로 설정하세요.
  2. 함수를 가상으로 만들지 마십시오.하지만 이것이 실제로 함수가 다른 정의에 의해 가려지는 것을 방지하지는 않습니다.

그 외에는 함수가 오버로드되는 것을 방지하고 하위 클래스에 대한 포인터/참조를 통해 호출할 수 있는 방식으로 함수를 잠그는 언어 기능에 대해 알지 못합니다.

행운을 빌어요!

다른 팁

당신이 사용할 수있을 때 final 가상 메서드 지정자(C++11에서 도입됨)를 사용하면 그렇게 할 수 있습니다.인용하자면 내가 가장 좋아하는 문서 사이트:

가상 함수 선언에 사용되는 경우 final은 함수가 파생 클래스에 의해 재정의되지 않을 수 있음을 지정합니다.

다음과 같은 예에 맞게 조정되었습니다.

class Base {
public:
    virtual bool someGuaranteedResult() final { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

컴파일할 때:

$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’

Microsoft 컴파일러로 작업할 때 다음 사항도 살펴보십시오. sealed 예어.

당신이 찾고있는 것이 Java 언어와 동등한 것 같습니다. 결정적인 키워드는 메소드가 하위 클래스에 의해 재정의되는 것을 방지합니다..

처럼 다른 사람 여기 있어요 제안됨, 당신은 이것을 정말로 막을 수 없습니다.또한 이것은 오히려 자주 묻는 질문.

(a) 함수를 비공개로 만드는 것이 해결책이라고 생각하지 않습니다. 왜냐하면 파생 클래스에서 기본 클래스 함수를 숨길 뿐이기 때문입니다. 파생 클래스는 항상 동일한 시그니처를 사용하여 새 함수를 정의할 수 있습니다.(b) 함수를 가상이 아닌 것으로 만드는 것도 완전한 해결책이 아닙니다. 왜냐하면 파생 클래스가 동일한 함수를 재정의하는 경우 항상 컴파일 타임 바인딩, 즉 obj.someFunction()을 통해 파생 클래스 함수를 호출할 수 있기 때문입니다. 여기서 obj는 인스턴스입니다. 파생 클래스.

나는 이것을 할 수 있는 방법이 없다고 생각합니다. 또한 파생 클래스가 기본 클래스 함수를 재정의하는 것을 금지하기로 결정한 이유를 알고 싶습니다.

명확히 하자면, 여러분 대부분은 그의 질문을 오해했습니다.그는 메소드를 "재정의"하는 것에 대해 묻는 것이 아니라 "숨기기"를 방지할 수 있는 방법이 있는지 여부를 묻고 있습니다.그리고 간단한 대답은 "아무것도 없습니다!"입니다.

그의 예를 다시 한 번 들어보자

상위 클래스는 함수를 정의합니다.

int foo() { return 1; }

Parent를 상속받은 Child 클래스는 동일한 함수를 다시 정의합니다(재정의하지 않음).

int foo() { return 2; }

모든 프로그래밍 언어에서 이 작업을 수행할 수 있습니다.이 코드가 컴파일되는 것을 방지할 수 있는 방법은 없습니다(컴파일러 설정 제외).당신이 얻을 수 있는 최선의 방법은 부모의 메소드를 숨기고 있다는 경고입니다.하위 클래스를 호출하고 foo 메소드를 호출하면 2를 얻게 됩니다.실제로 코드가 깨졌습니다.

그가 묻고 있는 것은 이것이다.

가상이 아닌 상속 함수 X를 숨기는 것에 대한 컴파일 시간 경고입니다.

경고 대신 오류가 발생하도록 컴파일러 설정을 변경하십시오.

컴파일러가 경고하는 내용이 숨겨져 있는 것 같아요!!실제로 재정의되고 있습니까?

컴파일러는 경고를 표시할 수 있지만 포인터가 가리키는 객체의 실제 유형에 관계없이 포인터가 상위 클래스 유형인 경우 런타임 시 상위 클래스 메서드가 호출됩니다.

이건 재미 있네.귀하의 컴파일러를 위한 작은 독립형 테스트 프로그램을 만들어 보십시오.

나는 같은 것을 찾고 있었고 어제 이 [다소 오래된] 질문에 이르렀습니다.

오늘 나는 깔끔한 C++11 키워드를 발견했습니다. final .다음 독자들에게 도움이 될 것이라고 생각했습니다.

http://en.cppreference.com/w/cpp/언어/final

하위 클래스를 상위 클래스의 유형으로 지정하면 비가상 함수는 상위 클래스의 버전을 호출합니다.

즉:

Parent* obj = new Child();

메서드를 가상으로 만들지 않는 한 하위 클래스는 이를 재정의할 수 없습니다.하위 클래스에서 호출하지 못하게 하려면 비공개로 설정하세요.

따라서 기본적으로 C++는 원하는 대로 작동합니다.

다른 사람이 서브클래스에서 여러분의 함수와 동일한 이름을 사용하지 못하도록 막는 것은 여러분이 연결된 라이브러리에서 선언한 것과 동일한 전역 함수 이름을 다른 사람이 사용하지 못하도록 막는 것과 크게 다르지 않습니다.

다른 사람이 아닌 귀하의 코드를 사용하려는 사용자가 귀하의 코드를 참조하는 방법에 주의하고 올바른 포인터 유형을 사용하거나 정규화된 범위를 사용하기를 바랄 뿐입니다.

귀하의 예에서는 어떤 기능도 재정의되지 않습니다.대신 숨겨져 있습니다(일종의 오버로딩이 변질된 경우임).오류는 Child 클래스 코드에 있습니다.csmba가 제안한 대로, 여러분이 할 수 있는 일은 (가능한 경우) 컴파일러 설정을 변경하는 것뿐입니다.자체 기능을 숨기는 타사 라이브러리를 사용하지 않는 한 괜찮습니다.

기술적으로 가상 기능이 재정의되는 것을 방지할 수 있습니다.그러나 결코 더 이상 변경하거나 추가할 수 없습니다.그것은 도움이 충분하지 않습니다.faq lite에서 제안한 대로 함수 앞에 주석을 사용하는 것이 더 좋습니다.

C++ 메서드는 비공개이며 기본적으로 재정의할 수 없습니다.

  • 개인 메서드를 재정의할 수 없습니다.
  • 다음이 아닌 항목을 재정의할 수 없습니다.virtual 방법

아마도 과부하를 언급하고 있습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top