c++ - 在 C++ 中本地重新定义全局函数的实现
问题描述
我正在为现有的 C++ 应用程序编写一些测试代码,方法是编写一个包含main()
函数和一些辅助类的文件,并将其链接到应用程序其他类的目标文件。我无权访问源文件,只能访问我无法修改的标题和对象/库。
在我的测试代码中,我想输出一个巨大结构的字段子集。ostream& operator<<(ostream&, HugeStruct const&)
不幸的是,现有代码中已经有一个全局函数,它会转储所有内容。该函数在HugeStruct
的头文件中声明并在相应的源代码中实现。
有没有办法只在测试源中覆盖该函数而不让编译器和/或链接器抛出一个合适的?它是用 GCC 4.8.5 编译的。
编辑:
是的,我可以使用一些解决方法。
我可以使用打印功能(如评论中所建议的那样),但我喜欢链接<<
运算符的便利性。
我可以编写一个std::string out(HugeStruct const&)
函数,将字段输出到字符串并使用os << out(hs)
. 这就是我目前所做的,但感觉像是一种迂回的方式。
不过,我觉得这个问题在一般情况下很有趣。
解决方案
如果您可以修改标头,以真正覆盖实现,您可以:
- 标记
ostream& operator<<(ostream&, HugeStruct const&)
为内联 ostream& operator<<(ostream&, HugeStruct const&)
在 cpp 中实现- 确保你的新实现的 cpp 在链接命令中的旧目标文件之后
这是如何工作的:
inline
告诉链接器在找到多个定义时不要抱怨- C++ 标准说,如果你按照我说的去做,这是未定义的行为。
- 这意味着如果你这样做,程序员(你)不能期望一个正确的程序
- 实际上,(全部?)链接器从左到右处理符号并覆盖实现
我不推荐这个:) 该out
功能更安全。
我看到的另一种选择是使用重载解析:您必须确保您的本地operator<<
比提供的库更匹配。
您可以通过例如从ostream
您在测试文件中使用的派生来做到这一点。在这里,我将假设您使用std::cout
.
struct TestCout: public std::ostream{
// ...
};
TestCout& operator<<(TestCout& os, HugeStruct const&);
TestCout tcout;
tcout << huge_struct;
推荐阅读
- angularjs - AngularUI Calendar 获取事件对象后获取范围
- javascript - 如何在 React JSX 中映射包含 JSON 对象的数组?
- css - 是否可以在内联 svg 中使用 css 变量?
- firebase - 在 Ionic App 中使用 firebase 匿名身份验证是否安全?
- c# - 从 PictureBox 保存原始图像,不调整大小
- wordpress - 如何在新编辑器(古腾堡)的画廊块中将默认“链接”属性设置为“媒体”
- python - 像素元组的拆包列表
- spring - 是否可以将“JGiven Spring”与“JGiven JUnit 5”结合使用?
- visual-studio-code - 是否可以为 VSCode 中的所有 c++ 文件设置 task.json?
- android - 未找到 Android 开发设备