또는 __declspec (novtable)을 사용하여 알려진 다른 부정적인 영향이 있습니까? 어떤 문제에 대한 언급도 찾을 수없는 것 같습니다.추상 기본 클래스에서 __declspec (novtable)을 사용하면 어떤 방식 으로든 RTTI에 영향을 줍니까?
답변
MSCV는 one vptr per object and one vtbl per class
을 사용하여 RTTI 및 가상 함수와 같은 OO 메커니즘을 구현합니다.
RTTI와 가상 함수는 vptr이 올바르게 설정된 경우에만 제대로 작동합니다.
struct __declspec(novtable) B {
virtual void f() = 0;
};
struct D1 : B {
D1() {
} // after the construction of D1, vptr will be set to vtbl of D1.
};
D1 d1; // after d has been fully constructed, vptr is correct.
B& b = d1; // so virtual functions and RTTI will work.
b.f(); // calls D1::f();
assert(dynamic_cast<D1*>(&b));
assert(typeid(b) == typeid(D1));
__declspec(novtable)
을 사용할 때 B는 추상 클래스 여야합니다.
D1의 생성자를 제외하고는 B의 인스턴스가 없습니다.
그리고 __declspec (novtable)에는 대부분의 경우 부정적인 영향이 없습니다.
그러나 파생 클래스 __declspec(novtable)
의 건설 중에는 ISO C++ 의미와 달라집니다.
struct D2 : B {
D2() { // when enter the constructor of D2 \
// the vtpr must be set to vptr of B \
// if B didn't use __declspec(novtable).
// virtual functions and RTTI will also work.
this->f(); // should calls B::f();
assert(typeid(*this) == typeid(B));
assert(!dynamic_cast<D2*>(this));
assert(dynamic_cast<B*>(this));
// but __declspec(novtable) will stop the compiler \
// from generating code to initialize the vptr.
// so the code above will crash because of uninitialized vptr.
}
};
참고 : virtual f() = 0
; f를 pure virtual function
으로, B를 추상 클래스로 만듭니다.
순수 가상 함수 could
(must
)의 definition
이 누락되었습니다.
C++에서는 권장하지 않는 생성자에서 가상 함수 호출을 허용합니다.
업데이트 : D2의 실수 : 파생 생성자의 vptr.
struct D3 : B { // ISO C++ semantic
D3() { // vptr must be set to vtbl of B before enter
} // vptr must be set to vtbl of D2 after leave
};
그러나 vptr은 생성 중에 불확정합니다. 이것은 생성자에서 가상 함수 호출이 권장되지 않는 이유 중 하나입니다.
D2 :: D2()의 vptr이 B이고 v :: b (f)의 정의가 누락 된 경우 vtbl의 포인터를 함수로 역 참조 할 때 this->f();
이 충돌합니다.
D2 :: D2()의 vptr이 B이고 B가 novtable을 사용하는 경우 초기화되지 않은 vptr을 참조 해제 할 때 this->f();
이 중단됩니다.
실제로 D2 :: D2()의 vptr은 MSVC (msvc8)의 D2입니다. 컴파일러는 D2 :: D2()에서 다른 코드를 실행하기 전에 vptr을 D2로 설정합니다.
따라서 this->f();
은 D2 :: f()를 호출하며 3 개의 어설 션은 위반됩니다.
기본적으로 이것은 (1) 생성자에서 가상 함수 호출이없고 (2) 순수 가상 함수가 실제로 호출되면 더 이상 "순수 가상 함수 호출"이라는 오류 정보를 얻지 않습니다. – paxos1977
정확하게 이해하면 ctor 또는 dtor 내의 가상 fn 호출은 컴파일 타임 링크로 변환됩니다. (c/d) tors에서 가상 fn 호출을 할 수 없습니다. 그 이유는 기본 클래스의 객체가 생성 될 때 파생 된 클래스에 대한 지식이 없으므로 파생 클래스를 호출 할 수 없으며 같은 논리가 적용되는 dtors를 사용할 수 없기 때문입니다.
- 1. 크론은 Getopt :: Long 모듈에 어떤 영향을 줍니까?
- 2. 거기에 어떤 방식 으로든 안드로이드에서 leaveclock 떠나거나 끝내는 이벤트가 있습니다
- 3. PHP의 '&'기호는 결과에 어떤 영향을 줍니까?
- 4. bash4는 bash 스크립팅에 어떤 영향을 줍니까?
- 5. JavaScript element.style = '무엇이든'이 HTML에 어떤 영향을 줍니까?
- 6. jQuery는 CSS 구조에 어떤 영향을 줍니까?
- 7. GraphicsPath.Flatten()은 그리기 성능에 어떤 영향을 줍니까?
- 8. Hashtable의 내용이 메모리의 크기에 어떤 영향을 줍니까?
- 9. 행 디자인이 MySQL 성능에 어떤 영향을 줍니까?
- 10. 정식 URL은 무엇이며 SEO에 어떤 영향을 줍니까?
- 11. 웹 크롤러는 사이트 통계에 어떤 영향을 줍니까?
- 12. 메서드 호출은 Java의 성능에 어떤 영향을 줍니까?
- 13. MEF는 응용 프로그램로드 시간에 어떤 영향을 줍니까?
- 14. XML 데이터를 activerecord 패턴으로 처리 : 어떤 방식 으로든?
- 15. ASP.NET MVC - 작업 이름이 URL에 어떤 영향을 줍니까?
- 16. 메서드 내에서 Linq 쿼리를 사용하면 지연된 실행에 영향을 줍니까?
- 17. 중첩이 효율성에 영향을 줍니까?
- 18. NUnit이 성능에 영향을 줍니까?
- 19. IHTTPModule 성능에 영향을 줍니까?
- 20. ADO.NET DataTable 제약 조건은 성능에 어떤 영향을 줍니까?
- 21. 내 웹 프로젝트에서 코드 계약을 사용하면 배포에 어떻게 영향을 줍니까?
- 22. 프로그램에서 여러 import 문을 사용하면 성능에 영향을 줍니까?
- 23. 리플렉션을 사용하여 추상 기본 클래스에서 생성자에 액세스
- 24. 기본 추상 클래스에서 서브 클래스 구성하기
- 25. 어떻게 RedirectToRoute가 SEO에 영향을 줍니까?
- 26. Linux에서 ACL이 성능에 영향을 줍니까
- 27. 브래킷 배치가 가독성에 영향을 줍니까?
- 28. URL의 길이가 레이아웃에 영향을 줍니까?
- 29. 추상 클래스가 아닌 부분 클래스를 사용하면 어떤 이점이 있습니까?
- 30. 공백 제거는 순위에 영향을 줍니까?
또한 관련 질문을 참조하십시오. http://stackoverflow.com/questions/1787752/ – paxos1977