c++ Primer Plus 学习记录(一)

osream和ofstream之:对象,继承和引用

ostream和ofstream类

ostream和ofstream类凸现了引用的一个有趣属性。ofstream对象可以使用ostream 类的方法, 这使得文件愉入/输出的格式与控制台输入/输出相同。使得能够将特性从一个类传递给另一个类的语言特性被称为继承,简单地说, ostream是基类(因为ofstrearn是建立在它的基础之上的而ofstream是派生类(因为它是从ostream派生而来的。派生类继承了基类的方法, 这意味抒ofstream对象可以使用基类的特性, 如格式化方法precision()和setf()。
继承的另一个特征是, 基类引用可以指向派生类对象,而无需进行强制类型转换。 这种特征的一个实际结果是,可以定义一个接受基类引用作为参数的函数,调用该函数时,可以将基类对象作为参数, 也可以将派生类对象作为参数。 例如, 参数类型为ostream&的函数可以接受ostrearn对象(如cout)或声明的ofstream对象作为参数.

程序通过调用同一个函数(只有函数调用参数不同)将数据写入文件和显示到屏幕上来说明了这一点 。 该程序要求用户输入望远镜物镜和一些目镜的焦距, 然后计算并显示每个目镜的放大倍数。 放 大倍数等千物镜的焦距除以目镜的焦距, 因此计算起来很简单。 该程序还使用了一些格式化方法, 这些方 法用千cout和ofstream对象(在这个例子中为fout)时作用相同。

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
const int LIMIT = 5;
void file_it(ostream& os, double fo, const double fe[], int n) 
{
    ios_base::fmtflags initial;
    initial = os.setf(ios_base::fixed);  //save initial formatting state
    os.precision(0);
    os << "Focal length of object: " << fo << "mm
";
    os.setf(ios::showpoint);
    os.precision(1);
    os.width(12);
    os << "f.1.eyepiece";
    os.width(15);
    os << "magnification" << endl;
    for (int i = 0; i < n; i++) {
        os.width(2);
        os << fe[i];
        os.width(15);
        os << int(fo / fe[i] + 0.5) << endl;

    }
    os.setf(initial);           //restore initial formatting state
}
int main() {
    ofstream fout;
    const char* fn = "ep-data.txt";
    fout.open(fn);
    if (!fout.is_open()) {
        cout << "Can't open " << fn << ".Bye
";
        exit(EXIT_FAILURE);
    }
    double objective;
    cout << "Enter the focal length of your "
        "telescope object in mm: ";
    cin >> objective;
    double eps[LIMIT];
    cout << "Enter the focal lengths, in mm, of " << LIMIT << " eyepieces:
";
    for (int i = 0; i < LIMIT; i++) {
        cout << "Eyepiece #" << i + i << ": ";
        cin >> eps[i];
    }
    file_it(fout, objective, eps, LIMIT);
    file_it(cout, objective, eps, LIMIT);
    cout << "Done
";
    return 0;
}

对于该程序, 最重要的一点是, 参数OS(其类型为ostream&)可以指向ostream对象(如cout), 也可以指向ofstream对象(如fout)。该程序还演示了如何使用ostream类中的格式化方法。 

setf()

setf()可以设置各种格式化状态。

setf(ios_base::fixed)将对象置于使用定点表示法的模式;

setf(ios_base::showpoint)将对象置千显示小数点的模式 , 即使小数部分为零。

precision()

precision()指定显示多少位小数(假定对象处于定点模式下)。所有这些设置都将一直保持不变,直到再次调用相应的 方法重新设置它们。

width()

width()设置下一次输出操作使用的字段宽度,这种设置只在显示下一个值时有效, 然后将恢复到默认设置。默认的字段宽度为零, 这意味右刚好能容纳下要显示的内容。

ios_base::fmtflags initial;
    initial = os.setf(ios_base::fixed);  //save initial formatting state
        os.setf(initial);           //restore initial formatting state

函数file_it()使用了两个有趣的方法调用

setf()返回调用它之前有效的所有格式化设置。 ios_base::fintflags是存储这种信息所需的数据类型名称。 因此 , 将返回值赋给initial将存储调用file_it()之前的格式化设置, 然后便可以使用变点initial作为 参数来调用setf(), 将所有的格式化设置恢复到原来的值。因此, 该函数将对象回到传递给file_it()之前的状态。

原文地址:https://www.cnblogs.com/Augustusben/p/14278967.html