在返回类型后加&什么意思

lly212 2009-08-12 05:49:51

#include <iostream>

class oper
{

friend std::ostream& operator<<(std::ostream& os, const oper& obj) // 返回值后面有个&
{
os << obj.data <<std::endl ;
return os ;
}

private :

int data;
};

以前没有带& 重载<< 显示需要把 std::ostream 改成 std::basic_ostream
我换了以后 换是很多错误 后来别人说的要加& 我问下加上后什么意思
换有为什么要不能用std::ostream 提示std::basic_ostream 什么意思
...全文
804 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
steven_007 2009-08-13
  • 打赏
  • 举报
回复
返回引用。
uwinb 2009-08-13
  • 打赏
  • 举报
回复
就算它勉强编译通过,你认为这样前后矛盾的代码,正常吗?
况且警告信息这么明确,你还问什么意思!
流对象不允许复制,主要不是出于效率考虑,而是要确保对流的操作不至于混乱。
操作流时依赖于很多内部状态,多个克隆体之间是不会自动同步这些状态。
ysysbaobei 2009-08-13
  • 打赏
  • 举报
回复
顶下
dongtaishaole 2009-08-13
  • 打赏
  • 举报
回复
g++ 不但可以编译,而且可以运行.............
lly212 2009-08-13
  • 打赏
  • 举报
回复
gcc 4.1.2
都编译成功 虽然那个gcc 加上 Wall 会有警告但是结果是对的
t.cc: In function ‘std::ostream& operator<<(std::ostream&, const oper&)’:
t.cc:19: 警告:在有返回值的函数中未发现 return 语句
t.cc: In function ‘std::istream& operator>>(std::istream&, oper&)’:
t.cc:24: 警告:在有返回值的函数中未发现 return 语句
t.cc: In function ‘std::ostream& operator<<(std::ostream&, const oper&)’:
t.cc:19: 警告:在有返回值的函数中,控制流程到达函数尾

我就怕方言c++ 所以我用现在兼容比较好的 dev-c++
直接过了

不知道编译什么意思
mstlq 2009-08-13
  • 打赏
  • 举报
回复
编译能过?

请楼主点击一下“rebuild”再试O(∩_∩)O
lly212 2009-08-13
  • 打赏
  • 举报
回复

#include <iostream>

class oper
{
public :

oper() : data(0) {}

oper(int i) : data(i) {}

void show()
{
std::cout << "the data is " << data << std::endl;
}

friend std::ostream& operator<<(std::ostream& os, const oper& obj)
{
os << obj.data <<std::endl ;
}

friend std::istream& operator>>(std::istream& is , oper& obj)
{
is >> obj.data ;//cin >> 后只跟变量 char ch ,,,
}

private :

int data;
};



int main()
{
oper obj1(10), obj2(12);
std::cout << obj1 << obj2;
std::cin.get();



上面那个因为中途有个" " 因为参数不是对象所以系统自己调用原来那个cout
你看上面的会以为我又错了 所以我改了下 改的和你一样
还有其实不用费那么多神 看一个函数的返回值 cout后跟一个对象就可以了 为什么要2个呢
Dave888Zhou 2009-08-13
  • 打赏
  • 举报
回复
不好意思,因为以前回贴时经常编译这样的代码,只要你不写"std::cout << obj1 << obj2"这样需要使用函数返回值的语句,编译是能通过的,所以我才说“只要不使用函数返回的值,当然没问题”。编译时一般会有警告信息,跟14楼的一样,即在有返回值的函数中未发现return语句。只要没有使用函数返回值,运行也不会有问题。因为我平时都是在Linux下学习和娱乐,使用的就是gcc了。Windows下的VC++编译器不知结果如何?(好久没用了)

但我不知道为什么有“std::cout << obj1 << obj2“这样的语句后,编译还能通过,而且运行没问题。因为从逻辑上分析这样是行不通的。

cout是ostream类的对象,因为它所指向的是标准设备(显示器屏幕),所以它在iostream头文件中作为全局对象进行定义:

ostream cout(stdout);//其默认指向的C中的标准设备名,作为其构造函数的参数使用。

  在iostream头文件中,ostream类对应每个基本数据类型都有其友元函数对左移操作符<<进行了友元函数的重载。

ostream& operator<<(ostream &out,int rhs);
ostream& operator<<(ostream &out,char *rhs);
//等等

  输出语句cout<<"www.cndev-lab.com"事实上调用的就是ostream& operator<<(ostream &out,char *rhs)这个运算符重载函数,由于返回的是流对象的引用,引用可以作为左值使用,所以当程序中有类似cout<<"www.cndev- lab.com"<<"abce"这样的语句出现的时候,就能够构成连续输出。

我们平时写代码都是按照规范来的,在operator<<,operator>>中例行地返回原来流对象的引用。很少会故意去删除一个return语句,然后看结果怎样。

你现在删除了return语句,那按理“std::cout<<obj1<<obj2” 调用的肯定不是上面那些基本数据类型的operator<< 重载版本,而是你自己在oper类中写的那个重载版本,我不知道为什么std::cout<<obj1没有返回值(因为没有return语句),但后面跟了<<obj2后还能通过。是不是编译器自动地就会帮你返回原来流对象的引用,还是它会自动地插入一个return语句。

这可能要去看标准库(特别是IO库)的实现原理以及实现源码吧,我现在还没看到这里呢,不好意思。
lly212 2009-08-13
  • 打赏
  • 举报
回复
std::cout<<oper1<<oper2;
这个语句相当于
opertator<<(operator<<(std::cout,oper1),oper2);
是因为返回的是operator所以你这么写 我认同 你肯定没有编译所以你说我错了

我把return os ; 删了也是对的 我编译过才说的 不信自己试试啊


#include <iostream>

class oper
{
public :

oper() : data(0) {}

oper(int i) : data(i) {}

void show()
{
std::cout << "the data is " << data << std::endl;
}

friend std::ostream& operator<<(std::ostream& os, const oper& obj)
{
os << obj.data <<std::endl ;
}

friend std::istream& operator>>(std::istream& is , oper& obj)
{
is >> obj.data ;//cin >> 后只跟变量 char ch ,,,
}

private :

int data;
};



int main()
{
oper obj1(10), obj2(12);
std::cout << obj1 << " " << obj2;
std::cin.get();
}



Dave888Zhou 2009-08-12
  • 打赏
  • 举报
回复
恰恰传入的参数用的是引用,返回的更应该用引用,这样我们的operator<<函数只需要通过一系列引用来操作其指向的外部对象,无需要创建任何的对象,提高的性能(这也是引用最重要的优势)。你在函数中使用的os,obj全部都是引用,指向的是传过来的对象,函数里面没有创建任何的对象,所有的一切都是通过引用来操作函数外面的对象的。这样你返回的引用仍然指向了那个原来的外部对象。

如果你去掉&,那就会返回一个临时对象(通过调用复制构造函数以复制os指向的那个对象来创建),而流是不允许复制的,至于原因,#4楼已经说得比较清楚了。而返回临时对象,需要创建开销,降低了性能。

你把把return os ; 删了,只要不使用函数返回的值,当然没问题。但是函数的签名上表明这是一个有返回值的函数(返回 std::ostream&引用),因此一旦你这样用:

std::cout<<oper1<<oper2;

那就会马上出错,这个语句相当于

opertator<<(operator<<(std::cout,oper1),oper2);

现在operator<<(std::cout,oper1)不能return一个值,那当然出错了。
lly212 2009-08-12
  • 打赏
  • 举报
回复
friend std::ostream& operator<<(std::ostream& os, const oper& obj)
我觉得既然传入的参数用的是std::ostream& os 为什么返回还是要加& 那std::ostream& os 的引用由什么用 我把return os ; 删了也是对的 那返回什么
如果是能具体说说不


yang_e_2009 2009-08-12
  • 打赏
  • 举报
回复
std::ostream& 返回流本身
std::ostream 返回该流的复制品

不过流是不允许复制的
zzandyc 2009-08-12
  • 打赏
  • 举报
回复
返回的是引用,即返回对象的别名,因为流不允许复制!
ZXW0521 2009-08-12
  • 打赏
  • 举报
回复
引用调用的意思吧
yshuise 2009-08-12
  • 打赏
  • 举报
回复
第一:引用效率高。
第二:可以链式输出:cout<< "kkk"<<"ddd"<<endl;
mstlq 2009-08-12
  • 打赏
  • 举报
回复
返回的是引用,返回的是os自己,一切正常……

如果不是返回引用,则相当于产生一个临时变量 std::ostream tmp(os),然后返回tmp(返回的其实不是os自身)……

再者std::ostream tmp(os)需要调用std::ostream的拷贝构造函数,很遗憾,这个函数似乎会调用用其父类std::io_base(貌似这名字)的拷贝构造函数,很不幸,那个拷贝构造函数是private的,于是编译器只好不让这样的代码通过编译了……
coverallwangp 2009-08-12
  • 打赏
  • 举报
回复
是引用类型
xxcclowlg 2009-08-12
  • 打赏
  • 举报
回复
取地址.
xingzhe2001 2009-08-12
  • 打赏
  • 举报
回复
std::ostream& 表示返回的是引用。不加返回的是个临时变量

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧