Nis*_*sba 2 c++ polymorphism operator-overloading
编辑:代码有一个错字,现在它编译但我仍然没有得到我想要的输出.
我试图重载流运营商std::cout,std::fstream等等,但我不能够正确处理多态性:我无法得到我想要看到的输出.我希望子类显示超类的内容,然后显示其内容,而超类只显示其内容.这可以通过在函数print_only_base()中引入一个新函数来实现Base,但我怀疑即使不添加新函数我也可以使代码工作.
我想得到什么
我有一个基类,它具有一些我希望在屏幕上显示的属性
Base base;
std::cout << base;
Run Code Online (Sandbox Code Playgroud)
有两类,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() {}
};
Run Code Online (Sandbox Code Playgroud)
主功能:
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;
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能获得理想的行为?
解决方案非常简单.
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() {}
};
Run Code Online (Sandbox Code Playgroud)
通过这些更改,我得到了所需的输出.请参阅https://ideone.com/x6ti3W.