有一个类A具有虚方法print()和重载运算符<<定义为朋友功能。
#include <iostream>
class A
{
public:
double a1, a2;
A(): a1(10.0), a2(10.0) {}
virtual void print ( std::ostream * o = &std::cout ) const
{
*o << a1<< '\t' << a2 << '\n';
}
friend std::ostream & operator << ( std::ostream & o, const A &aa )
{
o << aa.a1 << '\t' << aa.a2 << '\n';
return o;
}
};
类似于派生类B
class B : public A
{
public:
double b1, b2;
B(): A(), b1(20.0), b2(20.0) {}
virtual void print ( std::ostream * o = &std::cout ) const
{
A::print ( o );
*o << b1<< '\t' << b2;
}
friend std::ostream & operator << ( std::ostream & o, const B &bb )
{
o << (A)(bb);
o << bb.b1 << '\t' << bb.b2 << '\n';
return o;
}
};
我有以下问题:
1]有没有办法如何使用默认参数传递指向ostream对象的指针,以便运算符&lt;&lt;正确地替换了print()方法?这种重载是错误的
friend std::ostream & operator << ( std::ostream * o= &std::cout, const A &aa )
2]我不确定,如果派生类B中父类A的这一行调用操作符是正确的吗?
o << (A)(bb);
3]有没有更好的方法来重载operator&lt;&lt;没有&#34;朋友&#34;声明?
感谢您的帮助......
答案 0 :(得分:1)
如果没有友谊,你可以这样做:
#include <iostream>
class A
{
double a1, a2;
public:
A(): a1(10.0), a2(10.0) {}
virtual void print ( std::ostream * o = &std::cout ) const
{
*o << a1 << '\t' << a2;
}
};
std::ostream & operator << ( std::ostream & o, const A &aa )
{
o << "( )";
aa.print(&o);
return o << " )";
}
然后class B
没有operator<<
的单独版本,将会找到此版本,并在您向B::print
个实例传递时调用B
。< / p>
答案 1 :(得分:1)
我一直想知道如何避免冗长的朋友声明并提出以下建议:
template<typename T>
class OutEnabled {
public:
friend std::ostream& operator<<(std::ostream& out, T const& val) {
return static_cast<OutEnabled<T> const&>(val).ioprint(out);
}
friend QTextStream& operator<<(QTextStream& out, T const& val) {
return static_cast<OutEnabled<T> const&>(val).ioprint(out);
}
friend QDebug operator<<(QDebug dbg,T const& val) {
std::stringstream myStream;
myStream << val;
dbg.maybeSpace() << myStream.str().c_str();
return dbg;
}
protected:
template<typename U>
U& ioprint(U& out) const {
return static_cast<T const*>(this)->print(out);
}
};
class Foo:public OutEnabled<Foo>{
public:
Foo(){}
template<typename V>
V& print(V& out) const{return out<< "Bar";}
};
写这个我可以写:
std::cout << Foo();
qDebug() << Foo();
...
我经常使用这个概念,因为它允许您指定一个打印并将其用于不同的流。我必须至少使用我提到的三个,所以对我而言,这是值得的复杂性。这些朋友不在你的课堂上,所以打字很少,从继承中可以看出你的班级是可打印的。稍有不利的是,每个使用OutEnabled的类都有一个模板。