这是为派生类重载ostream& operator<<
而不重复基类代码的唯一方法吗?演员阵容不是要避免的吗?
我没有看到任何其他方式,除了在基类中定义某种类型的函数,它将表示基类的数据作为std :: operator&lt;&lt;可以“吃掉”(像一个字符串?),为派生类做同样的事情(在派生类流中调用基类流表示函数。当然是rep。函数)。
这个问题的理想解决方案是什么?
#include <iostream>
class Base
{
private:
int b_;
public:
Base()
:
b_()
{};
Base (int b)
:
b_(b)
{};
friend std::ostream& operator<<(std::ostream& os, const Base& b);
};
std::ostream& operator<< (std::ostream& os, const Base& b)
{
os << b.b_;
return os;
}
class Derived
:
public Base
{
private:
int d_;
public:
Derived()
:
d_()
{};
Derived (int b, int d)
:
Base(b),
d_(d)
{};
friend std::ostream& operator<<(std::ostream& os, const Derived& b);
};
std::ostream& operator<< (std::ostream& os, const Derived& b)
{
os << static_cast<const Base&>(b) << " " << b.d_;
return os;
}
using namespace std;
int main(int argc, const char *argv[])
{
Base b(4);
cout << b << endl;
Derived d(4,5);
cout << d << endl;
return 0;
}
答案 0 :(得分:6)
嗯......如果在没有正确定义结果的情况下进行投射,应该避免投射,但是投射到底座总是安全的。
可以通过考虑派生引用衰减到基本引用来避免显式转换,因此您可以使用隐式转换,如下例所示:
std::ostream& operator<< (std::ostream& os, const Derived& b)
{
const Base& bs = b;
os << bs << " " << b.d_;
return os;
}
答案 1 :(得分:5)
static_cast<const Base&>(b)
是安全的,并且没有任何错误,因为每个派生类对象也是一个Base类对象,可以像对待一样对待。
仅在以鲁莽的方式使用时,演员才是危险的,你必须在需要的时候以正确的方式使用演员表,这是他们按照语言标准提供的目的。
答案 2 :(得分:1)
你可以改变这样的事情:
struct Base {
int b_;
void print(ostream &o) { o << b_; }
};
struct Derived : Base {
int d_;
void print(ostream &o) {
Base::print(o);
o << ' ' << d_;
}
};
ostream &operator<<(ostream &o, Base &b) {
b.print(o);
return o;
}
ostream &operator<<(ostream &o, Derived &d) {
d.print(o);
return o;
}
如果Base
有虚函数(在本例中没有),则print
可能就是其中之一,你可以摆脱operator<<
的多重载荷
答案 3 :(得分:1)
如果您不喜欢演员表,您可以让您的操作员调用使用模板方法模式实现的writeTo
函数。
e.g。
class Base {
public:
std::ostream& writeTo(std::ostream& ostr) const { os << b_; return this->doWriteTo(os); }
private:
int b_;
virtual std::ostream& doWriteTo(std::ostream& ostr) const = 0; // pure virtual
};
class Derived {
private:
int d_;
virtual std::ostream& doWriteTo(std::ostream& ostr) const {return ostr << d_;}
};
std::ostream& operator<<(std::ostream& ostr, const Derived& d) {
return d.writeTo(ostr);
}
实际上,使用此模式,您可以为operator<<
一劳永逸地写Base
:
std::ostream& operator<<(std::ostream& ostr, const Base& b) {
return b.writeTo(ostr);
}
此模式也消除了将operator<<
设为friend
的需要。