子类中的重载流插入运算符 (<<)
Overloaded stream insertion operator (<<) in the sub-class
我有一个A类,我为它定义了一个(重载的)流插入运算符。我公开从这个 A 类派生一个 B 类,它有一个额外的数据成员。因此,我需要为派生类重新定义重载的流插入运算符,并且我是这样做的:
#include <iostream>
using namespace std;
class A {
int i;
char c;
public:
A(int i = 0, char c = ' ') {
this->i = i;
this->c = c;
}
friend ostream& operator << (ostream&, const A&);
};
class B : public A {
double d;
public:
B(int i = 0, char c = ' ', double d = 0.0) : A(i, c), d(d) {}
friend ostream& operator << (ostream&, const B&);
};
ostream& operator << (ostream& out, const A& a) {
out << "nInteger: " << a.i << "nCharacter: " << a.c << endl;
return out;
}
ostream& operator << (ostream& out, const B& b) {
out << b;
out << "nDouble: " << b.d << endl;
return out;
}
int main() {
A a(10, 'x');
B b(20, 'y', 5.23);
cout << b;
return 0;
}
问题1:这是一种合适的技术吗?如果没有,请让我知道我哪里出错了。
问题 2:运行时,此程序崩溃。为什么会这样?
支持此功能的一种常见方法是让重载运算符调用虚拟成员函数:
class A {
public:
virtual std::ostream &write(std::ostream &os) const {
// write self to os
os << "An";
return os;
}
};
class B : public A {
public:
virtual std::ostream &write(std::ostream &os) const {
// write self to os
// This can use the base class writer like:
A::write(os);
os << "Bn";
return os;
}
};
然后运算符重载只是调用该成员函数:
std::ostream &operator<<(std::ostream &os, A const &a) {
return a.write(os);
}
由于write
是虚拟的,并且您传递的是 A
by (const) 引用,因此这会根据实际类型调用正确的成员函数(即,A::write
对象是否真的是 A
的实例,B::write
如果它是 B
的实例)。
例如,我们可以像这样练习这些操作:
int main() {
A a;
B b;
std::cout << a << "n";
std::cout << b << "n";
}
。它产生这样的输出:
A
A
B
在实际使用中,您可能希望保护write
功能,并使operator<<
成为A
的朋友。
程序崩溃,因为第二个插入运算符调用自身:
ostream& operator << (ostream& out, const B& b) {
out << b; // <--YIKES!
out << "nDouble: " << b.d << endl;
return out;
}
一般来说,这是一个很好的方法,尽管我更喜欢给类一个公共虚拟print(ostream&) const
函数,并让插入运算符调用它。
相关文章:
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 如何显式调用运算符<<
- 为什么COUT在朋友函数中不起作用,该功能超载了操作员&lt;&lt;这是一个iStream运算符
- C++运算符<<调用::ostream而不是std::osttream
- BOOST ::变体无法解决运算符&lt;&lt;对于STD :: Ostream
- 过载输出<<用于类的运算符,以打印其中的元组
- C++ostream:没有运算符匹配<<&应在'&'代币
- 重载运算符<<:此运算符函数的参数太多
- C++继承运算符<<
- 重载运算符<<用于模板类.即使使用好友关键字也无法获得私人会员
- 如何过载<<用于YAML::Emitter的运算符,以序列化包含另一个自定义类的向量的自定义类
- 为什么字符串流运算符<<擦除原始值
- 关于使用运算符<<为新手提供C++中的模板
- 我已经完成了<<运算符重载,但它'It’不起作用
- 重载运算符<<输出地址而不是数据成员
- 错误:没有匹配'运算符<<"在'std::cout
- 重载运算符<<用于ostream语法
- 当运算符<存在时,为什么要定义 LT?
- log4cxx访问异常,使用<<运算符和宏
- 重载<<运算符错误C2804:二进制'运算符<<'参数太多