您的位置:首页 > 编程语言 > C语言/C++

C++标准库笔记:13.12.3 以辅助函数完成I/O

2017-06-12 08:54 393 查看
如果执行IO操作符时需要存取对象的私有成员,通常有以下两种方法:

使用辅助函数

IO操作符应该将实际任务委派给辅助的成员函数。这种技术允许具有多态性,如下:

class Fraction
{
public:
Fraction( int nNumerator = 0, int nDemominator = 1 )
:m_nNumerator( nNumerator ), m_nDemominator( nDemominator )
{}

//辅助输入输出函数
virtual void PrintOn( std::ostream& strm ) const
{
strm << m_nNumerator << '/' << m_nDemominator;
}
virtual void ScanFrom( std::istream& strm )
{
strm >> m_nNumerator;
strm.ignore(); //ignore '/'
strm >> m_nDemominator;
}

private:
int m_nNumerator;       //分子
int m_nDemominator;     //分母
};

std::ostream& operator << ( std::ostream& os, const Fraction& f )
{
f.PrintOn( os );
return os;
}

std::istream& operator >> ( std::istream& in, Fraction& f )
{
f.ScanFrom( in );
return in;
}


设置IO操作为类的友元函数

访问类的私有成员,也可以将IO操作符函数设计为类的友元函数

class Fraction
{
friend std::ostream& operator << ( std::ostream&, const Fraction&);
friend std::istream& operator >> ( std::istream&, Fraction& );
public:
Fraction( int nNumerator = 0, int nDemominator = 1 )
:m_nNumerator( nNumerator ), m_nDemominator( nDemominator )
{}

private:
int m_nNumerator;       //分子
int m_nDemominator;     //分母
};

std::ostream& operator << ( std::ostream& os, const Fraction& f )
{
os << f.m_nNumerator << '/' << f.m_nDemominator;
return os;
}

std::istream& operator >> ( std::istream& in, Fraction& f )
{
in >> f.m_nNumerator;
in.ignore(); //ignore '/'
in >> f.m_nDemominator;
return in;
}


对比

如果你的类不会作为其他类的基类,以上两种方法都一样。

否则的话,一旦用上继承,使用friend的方法就有很大的局限性。friend函数不能成为虚函数,所以程序可能会调用错误的函数。例如,某个基类引用实际指向一个派生类引用,并补当作input操作符的参数,则被调用的将是基类的操作符。为了避免出现这种情况,继承类不得实作自己的IO操作符,并且还要显示调用(因为不是虚函数)。

因此,使用第一种方法通用的多,尽管你在其它文件或书籍上看到的绝大多数例子使用的是friend函数,你最好将第一种方法视为标准作法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: