라이브러리는 클래스에 가상 함수를 제공합니다. 라이브러리에 동적으로 링크 된 바이너리를 다시 컴파일하지 않고도이 클래스를 새로운 가상 함수로 확장 할 수 있습니까?클라이언트 코드를 재 컴파일하지 않고 가상 인터페이스를 확장 할 수 있습니까?
표준으로는 가능하지 않습니다. 이것을 허용하는 플랫폼이 있습니까?
새로운 기능이 클래스 본문의 끝에 추가되는 것이 더 쉬울까요?
라이브러리는 클래스에 가상 함수를 제공합니다. 라이브러리에 동적으로 링크 된 바이너리를 다시 컴파일하지 않고도이 클래스를 새로운 가상 함수로 확장 할 수 있습니까?클라이언트 코드를 재 컴파일하지 않고 가상 인터페이스를 확장 할 수 있습니까?
표준으로는 가능하지 않습니다. 이것을 허용하는 플랫폼이 있습니까?
새로운 기능이 클래스 본문의 끝에 추가되는 것이 더 쉬울까요?
표준은 바이너리 호환성과 관련이 없습니다. 그것은 클래스와 관련이 있지만 클래스의 정의를 하나의 변환 단위에서 "변경"하여 실제로 정의되지 않은 동작을 호출하는 방식입니다.
대부분의 컴파일러는 다시 컴파일 할 필요없이 많은 변경을 허용하지만 목록은 작지만 ...이 경우에는 가능하지 않을 수도 있다고 말할 것입니다. 은 파생 된 사전 지식에 따라 다릅니다. 클래스.
필자가 예상하는 문제는 컴파일러가 일반적으로 가상 테이블에서 수행하는 최적화에 있습니다.
은 사용자가 가상 함수와 클래스를 만들 때, 당신이 그렇게 보이는 가상 테이블 얻을 : 파생 클래스 자신의 가상 함수는 일반적으로 "추가"일부 공간을 확보하기 위해
// B virtual table
0 - Offset to complete object
1 - RTTI
2 - func0
3 - func1
...
을 :
// D virtual table
Same as B
N+3 - func(N+1)
N+4 - func(N+2)
이 방법은 D
목적은 유형 (정적)을 B
(포인터 또는 참조를 통해) 경우에도 그대로 사용 할 수있는 것보다, 하나의 가상 포인터를 갖는다. 당신이 D
을 다시 컴파일하지 않고 B
을 연장한다면
그러나, 그것은 그냥 평범한 충돌, B
의 N+1
함수를 호출 할 때부터 대신 아마 같은 인수가없는 것 D
의 N+1
함수를 호출 할 것이다. .. 웁스!
을 알고있는 경우을 알면 자체 클래스의 가상 함수를 추가하지 않아도됩니다.
일부 라이브러리는 끝에 (일반적으로'reserved1','reserved2' 등으로 불리는) 더미 가상 함수를 추가하므로 나중에 이진 호환성을 손상시키지 않고 대체 할 수 있습니다. –
@Jan Hudec : 영리한 :) 저에게 여분의 비트를 생각하게 만듭니다 ^^ –
C++ 표준에는 ABI 호환성이 포함되어 있지 않습니다. 사실 그것은 동적 디스 패칭을 위해 vtable의 사용을 강제하지도 않습니다. 대부분의 (모든?) 컴파일러가 사용하는 구현 세부 사항 일뿐입니다. – rjnilsson
라이브러리 인터페이스를 확장하고 싶습니다. 기본 라이브러리 클래스를 인수로 사용하는 API 함수의 시그니처를 변경하지 않고이 작업을 수행 할 수있는 또 다른 방법이 있다면 그 사실을 알고 싶습니다. – Basilevs
KDE 프로젝트의 흥미로운 문서가 있습니다 : [C++의 이진 호환성 문제] (http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B). 읽으려는 다른 두 개의 문서에 대한 링크. – Mat