2009-03-11 2 views
4

d 포인터 클래스 정의에 새 멤버 함수를 추가해도 바이너리 호환성이 깨지지 않습니까?새로운 멤버 함수를 포인터 클래스 휴식 이진 호환성에 추가합니까?

예를 들어, 아래의 새 정의는 원본과 비교하여 바이너리 호환성을 손상시킬 수 있습니까? (? 측면 질문, 새로운 .so를 이진 호환성을 중단하는 경우 그렇지 않다면, 어떻게 수동으로 확인 할 이전 .so를 비교 말해하는 도구가 있습니까?)

원본 :

#ifndef __TESTBC_H__ 
#define __TESTBC_H__ 
class APrivate; 

class A 
{ 
    public: 
    int get() { d->update(); return _d->get(); } 

private: 
    APrivate *_d; 

}; 

class APrivate 
{ 
    public: 
    int get() { return _val; } 
    void update() { _val = 1; } 

    private: 
    int _val; 
}; 
#endif 

새로운 :

#ifndef __TESTBC_H__ 
#define __TESTBC_H__ 
class APrivate; 

class A 
{ 
    public: 
    int get() { _d->update(); return _d->get(); } 

private: 
    APrivate *_d; 

}; 

class APrivate 
{ 
    public: 
    int get() { return _val; } 
    void update() { _val = 1; multiply(); } 
    void multiply() { _val = _val * 10; } 

    private: 
    int _val; 
}; 
#endif 

FYI : 나는 포인터 클래스가 헤더 대신 cc 파일에 지정되어야한다고 생각합니다. 위 예제는 바이너리 호환성 문제에 중점을두기 위해 고안된 것입니다.

+0

타일을 개선 할 수 있습니다 ... 새로운 기능이 개인 클래스에 추가된다는 것을 명확하게 설명합니다. – IsaacS

답변

5

아니요.

C++에서 개체를 만드는 방법을 이해해야합니다.

비 가상 구성원 기능이있는 "POD"클래스에 가깝습니다. 이 함수는 객체의 표현을 메모리에 적용하지 않습니다. 따라서 새 버전 은 이전 버전과 이진 호환됩니다.

"APrivate"클래스를 사용자에게 노출시키지 않으면 그 이상입니다. ( 헤더를 전달 선언으로 지정하지 않으면) 훨씬 더 큰 변경을 수행하더라도 API를 제동하지 않습니다.

의미 :

#ifndef YOUR_PUBLIC_API 
#define YOUR_PUBLIC_API 
class bar; 
class foo { 
public: 
    // member functions using bar 
private: 
    bar *bar_; 
}; 
#endif 

심지어 bar 그래서 당신은 당신이 원하는 방식으로 변경 될 수 있습니다 노출하지 마십시오. C++ 라이브러리 ABI를 호환 가능하게 만드는 가장 좋은 방법은 입니다.

+0

API가 아니라 ABI라고 가정합니다. > "API를 제동하지 않겠습니다" – IsaacS

1

abi-compliance-checker 도구를 사용하여 헤더 파일과 공유 라이브러리를 확인하고 이진 호환성을 손상시킬 수있는 ABI 변경 사항을 검색합니다.

+0

abi-compliance-checker, AbiCC –