关于c++提取符号“>>”的重载问题

发现这样一个问题,cin>>的重载程序可以运行,但是却直接结束了。。。

百思不得其解,,,

看了半天,终于发现了原因。。。

这里是原来的代码。。。

#include<iostream>
using namespace std;
class app{
public:
	app(int a=0){};
	friend istream & operator>>(istream &in,const app &b);
	friend ostream & operator<<(ostream &in,const app &b);
private:
	int x;
};
istream & operator>>(istream &in,const app &b)
{
	in>>b.x;
	return in;
}
ostream & operator<<(ostream &out,const app &b)
{
	out<<b.x<<endl;
	return out;
}
void main()
{
	app A;
	cin>>A;
	cout<<A;
}

就是friend istream & operator>>(istream &in,const app &b);的原因。

因为用了const,所以导致了程序直接结束了。

正确做法是用 friend istream & operator>>(istream &in,app &b);

及去掉const,后面的实现部分也是如此。

这样,程序就可以正确的输入和输出了。

<think>好的,我现在需要回答用户关于C++中右移运算符>>的用法的问题。首先,我得回忆一下右移运算符的基本作用。右移运算符>>在C++中主要用于位操作,将二进制数向右移动指定位数,左侧补0或者符号位,这取决于数据类型。对于无符号数,左侧补0;有符号数则可能补符号位,即算术右移。 接下来,用户可能想知道具体的使用场景。比如,位操作中的快速乘除法。我记得右移一位相当于除以2,但要注意负数的情况。另外,在处理二进制数据或硬件寄存器时,右移操作也很常见。例如,从寄存器中提取特定位的信息,或者进行数据压缩存储,如引用[3]提到的标志位操作,虽然那里主要是用|=和&=,但移位操作也是基础。 然后,用户还可能关心运算符重载的情况。比如,在输入输出流中,>>被重载提取运算符,用于从cin或文件流中读取数据。例如,引用[2]提到cout<<p的问题,但这里涉及到的是左值重载,而右移运算符重载可能出现在自定义类型的输入操作中。不过用户的问题是右移运算符本身,所以可能需要区分位右移和流提取运算符的不同。 需要注意语法细节,比如位移的位数不能超过类型的位数,否则行为未定义。另外,移位运算的优先级较低,可能需要括号来确保运算顺序正确。 还要举一些例子,比如如何用右移实现除以2的幂次,或者如何提取特定位。例如,flags >> 3 将第3位移到最低位,再与1按位与,可以检查该位的值,类似于引用[3]中的检查标志位的方法,不过那里用的是左移。 最后,总结使用场景,包括位操作、优化运算、数据解析和运算符重载。同时,要指出算术右移和逻辑右移的区别,以及可能的陷阱,比如有符号数的右移结果依赖编译器实现,可能带来可移植性问题。 现在需要将这些点组织成结构清晰的回答,确保每个部分有例子,并且正确引用提供的资料。比如在讨论标志位时,引用[3]中的例子,虽然主要是关于|=和&=,但可以提到移位操作的基础作用。另外,运算符重载部分可以提到引用[2]中关于<<的重载,但用户问的是>>,需要明确区分。</think>### C++ 右移运算符 `>>` 的作用及使用场景 #### 1. **基本作用** 右移运算符 `>>` 用于将二进制数向右移动指定位数,左侧补0(逻辑右移)或符号位(算术右移),具体行为取决于数据类型: - **无符号整数**:左侧补0。 - **有符号整数**:通常补符号位(算术右移),但具体实现可能因编译器而异[^3]。 例如: ```cpp unsigned int a = 16; // 二进制 00010000 a = a >> 2; // 结果 00000100(十进制4) int b = -8; // 二进制补码表示(假设32位):11111111 11111111 11111111 11111000 b = b >> 1; // 结果 11111111 11111111 11111111 11111100(十进制-4) ``` --- #### 2. **常见使用场景** ##### (1) **快速除以2的幂次** 右移一位等价于整数除以2,右移n位等价于除以$2^n$(仅适用于非负整数): ```cpp int x = 16; x = x >> 3; // 等价于 16 / 8 = 2 ``` ##### (2) **提取或操作特定位** 结合按位与运算(`&`)可提取特定位: ```cpp int flags = 0b10101010; // 二进制值 int bit3 = (flags >> 3) & 1; // 提取第3位的值(结果为0) ``` 类似操作也用于标志位管理[^3]。 ##### (3) **数据压缩与解析** 在协议解析或数据存储中,右移可用于从字节流中提取字段: ```cpp uint32_t packet = 0x12345678; uint8_t high_byte = packet >> 24; // 提取最高字节0x12 ``` ##### (4) **运算符重载** 在输入流中,`>>` 被重载为**提取运算符**,用于读取数据: ```cpp int num; std::cin >> num; // 从输入流提取整数到num ``` 引用[^2]提到类似的重载逻辑可用于自定义类型的输入输出。 --- #### 3. **注意事项** - **有符号数的右移**:负数右移结果依赖编译器实现,可能影响可移植性。 - **位移位数限制**:若移动位数超过类型位数(如`int >> 32`),行为未定义。 - **优先级**:右移运算符优先级低于算术运算符,需用括号明确顺序: ```cpp int result = (a + b) >> 2; // 先计算a+b,再右移 ``` --- #### 4. **与左移运算符的对比** | 运算符 | 方向 | 效果 | 典型用例 | |--------|------|--------------------|--------------------| | `<<` | 左移 | 低位补0,高位丢弃 | 快速乘以$2^n$ | | `>>` | 右移 | 高位补0或符号位 | 快速除以$2^n$、位操作 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值