class B {
virtual int foo();
};
class D : public B {
virtual int foo() { cout<<"D\n"; }
};
int B::foo()
{
/* how do i tell if this->foo() is overridden by a subclass, or if it will */
/* simply recurse into B::foo()? */
this->foo();
}
main()
{
D d;
d.B::foo();
}
답변
가장 안전한 방법은 foo()를 오버라이드하지 않고 프로그래머를 신뢰할 수없는 경우 기본 클래스에서 호출되는 OnFoo() 함수를 재정의 할 수있게하는 것입니다. MFC는 재발 방지로부터 보호하기보다는 기본 동작을 보장하기 위해이 작업을 많이합니다.
정적 레벨에서도 OnFoo()를 구현하는 모든 것이 '파일에서 찾기'로 쉽게 발견됩니다.
예. .. 나는 심지어이 제공 싫어
class B
{
public:
B()
{
m_bInFoo=false;
}
int foo()
{
if(!m_bInFoo)
{
m_bInFoo=true;
int nRet = OnFoo();
m_bInFoo=false;
return nRet;
}
return 0;// probably throw exception
}
protected:
// inherited classes override OnFoo(), and never call OnFoo();
virtual int OnFoo(){ return 0 };
private:
bool m_bInFoo;
}
(문법/컴파일하지 스레드 테스트되지 않음)하지만 여기 내가 작동하는지 증명하려면 편집
int B::foo()
{
std::cout << "B" << std::endl;
if (typeid (*this) != typeid(B))
this->foo();
return 0;
}
입니다 MSVC++ 2010에서.
#include "stdafx.h"
#include <iostream>
class B {
public:
virtual int foo();
};
class D : public B {
public:
virtual int foo() {
std::cout<<"D\n"; return 0;
}
};
int B::foo()
{
std::cout << "B" << std::endl;
/* how do i tell if this->foo() is overridden by a subclass, or if it will */
/* simply recurse into B::foo()? */
if (typeid (*this) != typeid(B))
this->foo();
return 0;
}
int main(int argc, _TCHAR* argv[])
{
D d;
d.B::foo();
B b;
b.foo();
return 0;
}
B
D
B
증명 tput을 항상 여기에
변경 D를 작동하지 않습니다 그것은 더 이상
class D : public B { };
그건 작동하지 않습니다. foo()가 오버라이드되었는지 알려주지 않고 실제로 D 객체의 foo()를 호출 할 때 코드가 무한대로 재귀 될 것입니다. OP가 피하고 싶어하는 것. 실제로 foo()가 호출되는 B가 실제로 더 구체적 인 버전인지 아닌지 여부를 아는 데 도움이되지 않습니다. 바로 그 것입니다. 사람들이 대답의 유효성을 확인하기 전에 손을 건들지 않았다면 더 의미가 있습니다. –
@ Noah Roberts D가 B :: foo를 덮어 쓰지 않으면 재발합니다. 이는 스택 풀기를 사용하여 해결할 수도 있습니다. 같은 스택을 통해 B : foo()가 다시 입력되고 다른 변수를 만들려고 시도하면 B :: foo()를 입력 한 후 스레드 로컬 저장소에 플래그를 설정하는 변수를 만듭니다. 플래그가 설정되고 종료됩니다. 스택이 unwind되면 변수의 파기는 플래그를 해제 할 수 있습니다. 내 솔루션은 그가 겪었을 수있는 다른 시나리오를 읽지 않았으므로 그가 내린 정확한 문제를 해결합니다. –
한 가지 방법은 foo()
순수 가상 함수를 만드는 것입니다 작동하지 않습니다을 B
, 및으로 정의하십시오. 그렇게하면 B
의 파생 클래스는이어야하며 foo()
을 정의해야합니다. 여기서 B,
class B
{
public:
virtual int foo() = 0; //pure virtual function
};
//pure virtual function also has a default implementation!
int B::foo()
{
std::cout << "B" << std::endl;
this->foo(); //this will call the overridden foo() in the derived class!
return 0;
}
는 B의 파생 클래스는 foo는()를 구현하지 않는 경우에, 당신은 심지어 파생 클래스의 인스턴스를 만들 수 없습니다입니다!
는 ideone에서 전체 작업 코드를 참조하십시오 : 그런데 http://www.ideone.com/m8O2s, 내 개인적인 의견 일 것, 클래스와 같은 디자인으로 시작하는 것이 나쁘다. 파생 클래스 foo()에서 B::foo()
으로 전화하면 어떨까요? 재귀?
이렇게하면 B의 인스턴스를 인스턴스화 할 수 없습니다. B 유형의 객체를 계속 만들고 싶은지 여부는 알 수 없습니다. –
물론 주위에 엔지니어를 배치 할 수있는 방법이 많이 있지만 질문은 내가 원하는 것을하기 위해 C++ rtti에 내장 된 방법이 있는지입니다. – deltamind106
다른 사람들도 지적했듯이이를 수행 할 수있는 확실한 방법은 없습니다. 나는 당신이 당신의 디자인을 재고 할 것을 촉구한다 ...
글쎄, 예, 이전 개발자의 어색한 코드를 재 설계 할 수 있다면 좋겠지 만, 슬픈 코드는 현재 카드에 없습니다. – deltamind106
- 1. 파생 클래스의 기본 클래스의 공개 이벤트
- 2. VB.NET의 파생 클래스에서 기본 클래스의 속성이나 메서드를 사용하지 못하게하려면 어떻게해야합니까?
- 3. 파생 클래스는 기본 클래스의 정적 메서드를 호출해야하지만 재정의 된 속성은
- 4. 기본 클래스의 추상 메서드를 재정의합니다.
- 5. 기본 클래스와 파생 클래스의 런타임 유형 정보
- 6. C# 파생 클래스의 특성
- 7. Java에서 기본 클래스의 메서드는 파생 클래스의 재정의 메서드에서 어떻게 호출합니까?
- 8. 기본 클래스의 포인터를 통해 파생 클래스의 private 가상 메서드를 호출 할 수있는 이유는 무엇입니까?
- 9. 제네릭 메서드를 제네릭 클래스에서 파생
- 10. 파생 된 콘크리트, 클래스의 vtables
- 11. 파생 클래스의 속성 변경에 대한 기본 클래스 인식
- 12. 파생 클래스에서 기본 클래스의 구현을 호출 하시겠습니까?
- 13. 기본 클래스의 const 멤버를 파생 클래스로 초기화
- 14. 기본 클래스 및 파생 클래스의 정적 필드
- 15. 기본 클래스의 파생 클래스 'typedef 사용
- 16. 정의 된 기본 클래스의 메서드를 호출하는 파생 된 Ruby 클래스를 작성하려면 어떻게해야합니까?
- 17. 상속 : 파생 클래스의 파생 속성
- 18. 기본 클래스에서 정적 메서드를 실행할 때 파생 클래스의 클래스 이름을 가져 오는 방법은 무엇입니까?
- 19. 기본 클래스의 생성자와 소멸자가 파생 클래스와 함께 호출 되나요?
- 20. MATLAB에서 파생 클래스가 기본 함수를 호출하도록 강요 하시겠습니까?
- 21. 기본 클래스의 메서드를 통해 일반 유형을 반환하려면 어떻게해야합니까?
- 22. 하위 클래스가 메서드를 재정의하도록합니다.
- 23. 파생 클래스에 기본 클래스의 다중 요소 필드를 노출하는 방법
- 24. 디버깅을위한 클래스의 기본 메서드를 사용하고 계십니까?
- 25. 기본 클래스의 파생 클래스를 구별하는 가장 좋은 방법은 무엇입니까?
- 26. 파생 클래스가 메서드를 재정의하는 경우 기본 클래스 메서드가 호출되는 이유는 무엇입니까?
- 27. 기본 클래스는 파생 클래스의 보호 된 필드를 볼 수 있습니까?
- 28. 스프링 주석이있는 파생 클래스의 기본 클래스 속성 설정
- 29. C# : 기본 생성자에서 파생 클래스의 const 변수를 사용하는 방법
- 30. 기본 클래스의 초기화 프로그램
확실한 방법은 없을 것이다. 왜 그러고 싶니? –
나는 일반인과 마찬가지로 dli.foo()에 전화하여 동의합니다. – Puppy
개인적인 견해에 대한 답을 보충하고 싶습니다. 나는 왜 누군가가 무언가를하고 싶어하는지 결코 의심하지 않으려 고 최선을 다한다. 나는 그들이 왜 무언가를하고 싶은지를 알 수 없다. 나는 그들이 질문을했다는 것을 알고있다.나는 그들의 문제를 해결하고 해결할 대안을 제공하는 것이 좋다고 생각하지만, "보통 사람처럼"하는 말은 건설적이거나 도움이되지 않습니다. –