"Essential C++" : 提供 iostream 运算符的类实例
"Essential C++": Providing Class Instances of the iostream Operators
来自Essential C++:4.10提供iostream运算符的类实例
通常,我们希望同时读取和写入类的对象。例如为了显示我们的trian类对象,我们希望能够编写
cout << train << endl;
为了支持这一点,我们必须提供一个重载的输出实例操作员:
ostream& operator<< (ostream &os, const Triangular &rhs)
{
os << "(" << rhs.beg_pos() << "," << rhs.length() << ")";
rhs.display(rhs.length(), rhs.beg_pos(), os);
return os;
}
我们返回传递到函数中的同一个ostream对象。这允许连接多个outptu运算符。两个对象都是通过引用传递ostream操作数未声明为const因为每个输出操作都会修改ostream对象
我有点困惑为什么ostream操作数不能声明为const。如果输出运算符声明如下:
const ostream& operator<< (const ostream &os, const Triangular &rhs)
上述声明有什么问题吗?
感谢
问题是,如果ostream
参数(或相反的istream
)是常量引用,则运算符将无法修改流对象。流的插入/提取修改流状态,因此现有的operator<<
是非常量操作。这反过来意味着,虽然您可以声明,甚至定义:
std::ostream const & operator<<( std::ostream const & s, Type const & t );
问题是,该定义实际上根本无法将任何内容写入流中:
std::ostream const & operator<<( std::ostream const & s, Type const & t ) {
s << "Hi"; // Error: operator<<( std::ostream&, const char*) requires a
// non-const `std::ostream&`
return s; // This is fine
}
输出变量rhs
时,如果os
是ofstream
,则必须修改ostream& os
内的一些数据成员,如输出缓冲区或文件写入位置。
将os
声明为const
禁止这样的修改。
并且,如图所示,如果os
被声明为const
,则不能使用它来输出基元数据类型,因为ostream::operator<<()
都没有被声明为常量成员函数。
相关文章:
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 重载运算符*以获取对另一个类的实例的引用
- 清除具有已删除赋值运算符的成员的类实例
- 为什么找不到使用命名空间中定义的类型实例化的 std::weak_ptr 的重载运算符==?
- 是否可以在实例方法中使用带有"this"的重载运算符?
- 如何实现赋值运算符,使多个实例共享公共数据
- 防止为字符串流提取运算符不支持的类型实例化模板类 (>>)
- 运算符*=来自两个实例(矩阵),结果不好
- 如何超载分配运算符,该操作员总计两个实例变量
- Visual Studio无法在布尔运算的上下文中实例化强制转换运算符模板(T=bool)
- 将类实例作为指针传递,并在此指针上使用过载的下标运算符
- C++ 重载流运算符、引用参数和匿名实例
- 扩展模板化类以在对象实例上具有运算符 bool<bool>
- "Essential C++" : 提供 iostream 运算符的类实例
- C++-虚拟运算符=在派生实例的基类上调用
- 覆盖运算符 =,以便我们可以使用 = 复制类实例,而不会有浅层复制问题
- 将赋值运算符与类实例和向量一起使用
- 以类实例为右侧的运算符重载
- 将模板化适配器编译错误作为运算符重载实例的 rhs
- 模板化赋值运算符模板实例化失败