运算符>>中的常量行为
Const behavior in operator >>
让我们考虑以下代码(实时:http://ideone.com/3Ky4Kr)
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
class StrStrTest {
public:
StrStrTest(const std::string& ba) {
a = (char*)calloc(1, ba.length() + 1);
strcpy(a, ba.c_str());
}
virtual ~StrStrTest() {
free(a);
}
private:
char* a;
friend std::basic_ostream<char>& operator << (std::basic_ostream<char>& ss, const StrStrTest& a);
friend std::basic_istream<char>& operator >> (std::basic_istream<char>& ss,const StrStrTest& a);
};
std::basic_ostream<char>& operator << (std::basic_ostream<char>& ss, const StrStrTest& a) {
ss << a.a;
return ss;
}
std::basic_istream<char>& operator >> (std::basic_istream<char>& ss,
const StrStrTest& a) {
ss >> a.a; // <<-- HERE
// a.a = NULL;
return ss;
}
int main()
{
StrStrTest bb("foo");
std::cin >> bb;
std::cout << bb;
}
首先,为什么要编译?在标有 <<的行上——这里我(巧妙地)修改了一个const
对象。(显然a.a = NULL;
不编译,这太明显了)。
其次,这是否会导致未定义的行为?
PS:请不要认为代码不安全,可能会覆盖它不拥有的内存,char*
vs. std::string
等...我知道这些,这不是问题的重点,这不是生产代码。
您使用的重载是这样的:operator>>(std::istream&, char*)
.它需要char*
,按值。它不会修改指针(即它不会将指针更改为指向其他地方)。它修改指针保存其地址的数据,将一个以空结尾的 c 字符串写入该位置。因此,对象的恒定性没有被违反,因为该数据不是对象的一部分。
如果您尝试执行以下操作:
a.a = NULL;
这是修改对象的成员,因此是不允许的。
其次,这是否会导致未定义的行为?
如果a.a
没有指向正确分配的内存,并且有足够的空间用于流中的下一个空格分隔的字符数据,则可以。但不是与StrStrTest
对象的恒定性有关的任何结果。
相关文章:
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 通过多个头文件使用常量变量
- 在cuda线程之间共享大量常量数据
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 是默认情况下分配给char数组常量的值
- 私有类型的静态常量成员
- 类似枚举的计算常量
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么我可以通过引用修改常量返回
- 如何创建长度由常量参数指定的数组
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 隐式常量/非常量运算符布尔
- 非常量变量只读位置的赋值
- EASTL矢量<向量<int>>连续的