dポインタークラスに新しいメンバー関数を追加すると、バイナリ互換性が失われますか?
-
10-07-2019 - |
質問
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:dポインタークラスは、ヘッダーではなくccファイルで指定する必要があることを理解しています。上記の例は、バイナリ互換性の問題に焦点を当てるために考案されています。
解決
いいえ、そうではありません。
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互換にする最適な方法。
他のヒント
abi-compliance-checker ツールの使用を検討し、ヘッダーファイルをチェックしますライブラリを共有し、バイナリ互換性を壊す可能性のあるABIの変更を検索します。
所属していません StackOverflow