编辑:代码有错字,现在可以编译了,但我仍然没有得到我想要的输出。
我正在尝试为 std::cout
、std::fstream
等重载流运算符,但我无法正确处理多态性:我我无法获得我想要看到的输出。
我希望子类显示父类(super class)的内容,然后显示其内容,而父类(super class)只显示其内容。
这可以通过在 Base
函数中引入一个新函数 print_only_base()
来实现,但我怀疑即使不添加新函数我也可以使代码工作。
我想得到什么
我有一个基类,它有一些我想在屏幕上显示的属性
Base base;
std::cout << base;
有两个类,A
和 B
继承自 Base
。 Base
是一个多态类,A
和 B
在流式传输时显示不同的输出。
我希望 Base
类的对象仅显示其输出,而 A
类的对象(B
相同)如果将输出视为 Base
的实例,则首先显示输出本身,然后将输出本身视为 A
(或 B
)。
在代码下方我写下了我期望的输出和我的(不工作的)尝试。
#include <iostream>
class Base {
virtual std::ostream & print(std::ostream stream) const {
stream << "Base class output\n";
return stream;
}
public:
friend std::ostream & operator<<(std::ostream & stream, const Base & obj) {
return obj.print(stream);
}
virtual ~Base() {}
};
class A : public Base {
std::ostream & print(std::ostream & stream) const {
stream << "foo = " << foo << "\n";
return stream;
}
int foo = 0;
public:
friend std::ostream & operator<<(std::ostream & stream, const A & obj) {
// here I would like to call the base class for printing, but I would enter in an infinite loop
return obj.print(stream);
}
~A() {}
};
class B : public Base {
std::ostream & print(std::ostream & stream) const {
stream << "bar = " << bar << "\n";
return stream;
}
int bar = 0;
public:
friend std::ostream & operator<<(std::ostream & stream, const B & obj) {
// here I would like to call the base class for printing, but I would enter in an infinite loop
return obj.print(stream);
}
~B() {}
};
主要功能:
int main(int argc, char * argv[]) {
Base * base = new Base();
A * a = new A();
B * b = new B();
Base * a_inside = dynamic_cast<Base *>(a);
std::cout << *base << "\n";
std::cout << *a << "\n";
std::cout << *b << "\n";
std::cout << *a_inside << "\n";
delete base;
delete a;
delete b;
/* output I want to get
Base class output
Base class output
foo = 0
Base class output
bar = 0
Base class output
foo = 0
*/
return 0;
}
如何获得所需的行为?
最佳答案
解决方案非常简单。
- 定义
operator<<
仅对基类起作用。无需为派生类型定义它。 - 依靠
virtual
调用print
的功能机制派生类的功能。 - 添加代码以调用
Base::print
从派生类中打印派生类的特定内容之前。确保函数不是private
在基类中。
#include <iostream>
class Base {
protected:
virtual std::ostream & print(std::ostream& stream) const {
stream << "Base class output\n";
return stream;
}
public:
// Define it only for the base class.
friend std::ostream & operator<<(std::ostream & stream, const Base & obj) {
return obj.print(stream);
}
virtual ~Base() {}
};
class A : public Base {
std::ostream & print(std::ostream & stream) const {
// Print the base class specific information first.
Base::print(stream);
// Print the derived class specific information.
stream << "foo = " << foo << "\n";
return stream;
}
int foo = 0;
public:
~A() {}
};
class B : public Base {
std::ostream & print(std::ostream & stream) const {
// Print the base class-specific information first.
Base::print(stream);
// Print the derived class specific information.
stream << "bar = " << bar << "\n";
return stream;
}
int bar = 0;
public:
~B() {}
};
通过这些更改,我得到了所需的输出。看到它在 https://ideone.com/x6ti3W 工作.
关于c++ - 如何正确重载流运算符以在多态类中进行打印?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49903769/