gpt4 book ai didi

c++ - 拆分长方法维护类接口(interface)

转载 作者:行者123 更新时间:2023-11-30 04:30:57 25 4
gpt4 key购买 nike

在我的库中有这样一个类:

class Foo {
public:
void doSomething();
};

现在,doSomething() 的实现已经增长了很多,我想将它分成两种方法:

class Foo {
public:
void doSomething();
private:
void doSomething1();
void doSomething2();
};

doSomething() 实现是这样的:

void Foo::doSomething() {
this->doSomething1();
this->doSomething2();
}

但是现在类接口(interface)已经改变了。如果我编译这个库,所有使用这个库的现有应用程序都将无法运行,外部链接被更改。

如何避免破坏二进制兼容性?

我想内联可以解决这个问题。这样对吗?它是可移植的吗?如果编译器优化取消内联这些方法会怎样?

class Foo {
public:
void doSomething();
private:
inline void doSomething1();
inline void doSomething2();
};

void Foo::doSomething1() {
/* some code here */
}

void Foo::doSomething2() {
/* some code here */
}

void Foo::doSomething() {
this->doSomething1();
this->doSomething2();
}

编辑:我在方法拆分前后测试了这段代码,它似乎保持了二进制兼容性。但我不确定这是否适用于每个操作系统和每个编译器以及更复杂的类(使用虚拟方法、继承......)。有时我在添加这些私有(private)方法后会破坏二进制兼容性,但现在我不记得是在哪种特定情况下发生的。可能是因为符号表是按索引查找的(就像 Steve Jessop 在他的回答中指出的那样)。

最佳答案

严格来说,根本改变类定义(以您显示的任何一种方式)都违反了单一定义规则并导致未定义的行为。

在实践中,向类中添加非虚拟成员函数可以在每个实现中保持二进制兼容性,因为如果不这样做,那么您将失去动态库的大部分好处。但是 C++ 标准并没有说明很多(什么?)关于动态库或二进制兼容性,因此它不能保证您可以进行哪些更改。

因此在实践中,如果动态链接器按名称在符号表中查找条目,则更改符号表并不重要。符号表中的条目比以前多了,但这没关系,因为所有旧条目仍然具有相同的错位名称。可能在您的实现中,私有(private)和/或内联函数(或您指定的任何函数)不是 dll 导出的,但您不需要依赖它。

我使用过一个系统(Symbian),其中符号表中的条目不是按名称查找的,而是按索引查找的。在那个系统上,当你向动态库中添加任何东西时,你必须确保所有新函数都被添加到符号表的末尾,你可以通过在一个特殊的配置文件中列出所需的顺序来做到这一点。您可以确保二进制兼容性没有被破坏,但它相当乏味。

因此,您可以检查您的 C++ ABI 或编译器/链接器文档以确保绝对确定,或者相信我的话然后继续。

关于c++ - 拆分长方法维护类接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8413873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com