在 d 指针类中添加新成员函数是否会破坏二进制兼容性?

发布于 2024-07-15 08:08:24 字数 914 浏览 11 评论 0原文

在 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

仅供参考:我理解 d 指针类应该是在 cc 文件而不是 header 中指定。 上面的示例旨在关注二进制兼容性问题。

Will adding new member function into d pointer class definition break binary compatibility?

For example, will the new definition below break binary compatibility compared to the original? (side question, is there a tool that will tell me if a new .so breaks binary compatibility compared to the old .so? If not, how do I check manually?)

Original:

#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

New:

#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: I understand d pointer class should be specified in the cc file instead of header. above example is contrived to focus on binary compatibility issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暗地喜欢 2024-07-22 08:08:24

不,不是的。

您应该了解 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 兼容的最佳方法。

No it does not.

You should understand how C++ builds its objects.

In your case it is just almost "POD" class with non-virtual member functions. These
functions do not affet the representation of object in memory. Thus new version
is binary compatible with old.

More then that, if you do not expose your "APrivate" class to user. (Not giving
a header just forward declaration), you would not brake an API even if you do much bigger
changes.

Meaning:

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

You do not even expose bar so you may change it in any way you wish. it is the
best way to make C++ libraries ABI compatible.

飘过的浮云 2024-07-22 08:08:24

考虑使用 abi-compliance-checker 工具,它检查头文件和共享库并搜索可能破坏二进制兼容性的 ABI 更改。

Consider using the abi-compliance-checker tool, it checks header files and shared libs and searches for ABI changes that may break binary compatibility.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文