拆分维护类接口的长方法
Splitting long method maintaining class interface
在我的库中有这样一个类:
class Foo {
public:
void doSomething();
};
现在,doSomething()
的实现已经增长了很多,我想把它分成两种方法:
class Foo {
public:
void doSomething();
private:
void doSomething1();
void doSomething2();
};
doSomething()
的实现是这样的:
void Foo::doSomething() {
this->doSomething1();
this->doSomething2();
}
但是现在类接口发生了变化。如果我编译这个库,所有使用这个库的现有应用程序都不能工作,外部链接被改变。
如何避免破坏二进制兼容性?
我想内联解决了这个问题。对吗?它是便携的吗?如果编译器优化未内联这些方法会发生什么?
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();
}
编辑:我在方法分裂之前和之后测试了这段代码,它似乎保持了二进制兼容性。但我不确定这是否适用于每个操作系统和每个编译器以及更复杂的类(虚拟方法,继承…)。有时,在添加这样的私有方法后,我的二进制兼容性会中断,但现在我不记得是在哪种特殊情况下了。也许是由于按索引查找的符号表(如Steve Jessop在他的回答中注释)。
严格地说,更改类定义(以您所显示的任何一种方式)都违反了单一定义规则,并导致未定义的行为。
在实践中,向类中添加非虚成员函数可以在每种实现中保持二进制兼容性,因为如果不这样做,就会失去动态库的大部分好处。但是c++标准并没有对动态库或二进制兼容性说太多(任何?),所以它不能保证你能做什么改变。
因此,在实践中,只要动态链接器按名称查找符号表中的项,更改符号表并不重要。符号表中的条目比以前多了,但这没关系,因为所有旧的条目仍然具有相同的混乱名称。可能在你的实现中,私有和/或内联函数(或你指定的任何函数)没有全部导出,但你不需要依赖于它。
我使用过一个系统(Symbian),符号表中的条目不是按名称查找的,而是按索引查找的。在该系统上,当您向动态库添加任何内容时,您必须确保将任何新函数添加到符号表的末尾,这可以通过在特殊配置文件中列出所需的顺序来实现。您可以确保二进制兼容性没有被破坏,但这相当乏味。
所以,你可以检查你的c++ ABI或编译器/链接器文档来绝对确定,或者只是相信我的话,然后继续。
这里没有问题。
Foo::doSomething()
的name mangling总是相同的,无论它的实现。我认为如果添加非虚方法,类的ABI不会改变,因为非虚方法不存储在类对象中,而是作为具有混乱名称的函数。只要不添加类成员,就可以添加任意多的函数。
- 类接口,可以创建N个方法
- 如何使用接口指针调用方法,该指针是其具体类的一部分,而不是接口的一部分
- C++接口继承不同的参数方法
- 并发安全堆栈接口方法:正确与否?
- 无法将__str__特殊方法与Boost::Python接口
- Java(或C++)如何处理接口中定义的方法的调用
- 抽象类/接口中的空方法是否被认为是一种好的做法?
- 如何在 Iaccessible 接口的 accLoacation() 方法中启动参数?
- 这是重载提供与非静态成员函数相同接口的静态成员函数的优雅方法吗?
- C++创建具有可变参数模板方法的接口
- 创建接口和混凝土类并在向量中使用它们会导致调用方法时的怪异行为
- 在C 11或更高版本中,是否可以通过Lambda来实现单方法纯Virtual C 接口
- 通过其方法的子集实现接口
- 在没有包装程序类的情况下,在ActiveX接口上调用方法
- C ++类实现接口,接口具有采用任何实现该接口的类的方法
- 正在接口构造函数中调用重写的接口方法
- 接口和公共方法
- 在自定义 C/C++ 程序中获取 PPP0 接口 Tx/Rx 字节的最简单方法是什么?
- 当从一个应用程序调用时,在DLL方法中创建COM接口指针是有效的,但当从另一个应用软件调用时则无效
- 接口描述中接口方法的预定义参数列表