如何解决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&)
标记为内联 - 在 cpp 中实现
ostream& operator<<(ostream&,HugeStruct const&)
- 确保带有新实现的 cpp 位于链接命令中的旧目标文件之后
这是如何工作的:
-
inline
告诉链接器在找到多个定义时不要抱怨 - C++ 标准说如果你按照我告诉你的去做,这是未定义的行为。
- 这意味着如果你这样做,程序员(你)就不能期待一个正确的程序
- 实际上,(所有?)链接器从左到右处理符号并覆盖实现
我不建议这样做:) out
函数更安全。
我看到的另一个选择是使用重载解析:
您必须确保您本地的 operator<<
比图书馆提供的更匹配。
您可以通过例如从您在测试文件中使用的 ostream
派生来做到这一点。这里我假设您使用 std::cout
。
struct TestCout: public std::ostream{
// ...
};
TestCout& operator<<(TestCout& os,HugeStruct const&);
TestCout tcout;
tcout << huge_struct;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。