能否将&CustomType或*CustomType传入C++流插入运算符?
剧透提醒:我在头文件中漏写了*,代码编译通过但忽略了我的运算符重载,只打印了地址。
导致这个混乱的问题,非常抱歉!谢谢大家!
核心问题分析
你碰到的问题本质是类型不匹配:你重载的是接受TEST&(对象引用)的operator<<,但代码里传给cout的是TEST*(对象指针)。标准库本身就有打印指针地址的默认重载ostream& operator<<(ostream&, const void*),编译器自然会优先匹配这个最贴合的版本,完全不会搭理你的重载。
另外你误解了解引用的拷贝问题:解引用指针后传给接受引用的operator<<不会产生任何类实例拷贝——引用只是原对象的别名,不会在栈上创建新的实例,完全符合你“无拷贝输出”的要求。
解决方案1:解引用指针(最简单,无拷贝)
直接修改main里的调用,解引用指针后传递给你的重载函数即可:
int main() { TEST var("tester", 22); cout << *&var; // 解引用指针,调用你的重载版本,无拷贝 TEST* ptr = &var; cout << *ptr; // 同样无拷贝,直接输出对象内容 return 0; }
解决方案2:重载指针版本的operator<<(无需解引用)
如果你就是想直接用指针调用<<而不解引用,可以专门重载一个接受TEST*的版本,编译器会直接匹配它,同样不会产生类拷贝:
#include <iostream> using namespace std; class TEST { public: string name; int id; TEST(string nname, int iid) : name(nname), id(iid) {} }; // 原有的引用版本(保留,支持直接传对象或解引用指针) std::ostream& operator<<(std::ostream& out, TEST &m) { return out << "Test Output, class has values: ID" << m.id << "; NAME: " << m.name; } // 新增指针版本的重载,复用引用版本的逻辑避免重复代码 std::ostream& operator<<(std::ostream& out, TEST* m) { return out << *m; } int main() { TEST var("tester", 22); cout << &var; // 现在会调用你重载的指针版本,输出对象内容 cout << (TEST*) &var; // 同样匹配指针版本 return 0; }
关于你的临时解决方案
你的临时方案里的operator<<(std::ostream& out, TEST m)是按值传递,反而会产生类实例的拷贝,违背了你“无拷贝”的要求。其实你可以直接用指针调用display函数:
TEST* ptr = &var; ptr->display(cout);
但显然重载operator<<的方式更符合C++的惯用语法。
关于“涡轮鱼运算符”的问题
C++里没有类似Rust涡轮鱼的语法来强制指定运算符版本,但你可以通过显式调用函数的方式指定:
// 显式调用你的重载函数 operator<<(cout, *&var);
不过这完全没必要,前面的两种解决方案已经更优雅地解决了问题。
内容的提问来源于stack exchange,提问作者Darksilvian
相关产品推荐
相关产品推荐

