Thinking in C++ 卷2中文版

本文介绍了C++中的IO流概念,强调其简化和安全性的优势,并通过FileClass示例展示了如何封装stdio FILE指针,确保文件正确打开和关闭。内容包括IO流的改进、文件操作、字符串流和标准控制流的使用,以及FileClass的构造、析构和成员函数的实现。

让我们对bruceeckel的开源精神致以崇高的敬意

IO

 You can do much more with the general I/O problem than just take standard I/O and turn it into a class

   如果你能产生通常看起来一样的容器——标准IO,文件,甚至内存块,以致于你只须仅仅记住一个接口,难道这不是很好的吗?这就是IO流背后的思想。他们更加简单,安全,甚至有时候比标准c stdio库的多样函数更有效率。

  IO流类通常是C++新程序员学习使用C++类库的第一部分。本章将讨论IO流是如何在c stdio组件上改进的,如何察看文件,字符串流以及标准控制流的行为的。

为什么是IO

你可能想了解旧的表现良好的c库有何缺陷。为什么不用类对C库进行包装而再使用它呢?有时候这是一个好的解决办法。例如,假定你想证实一个stdio FILE指针指向的文件已经安全的打开了,以及不需要依靠程序员调用close( )函数就恰当的关闭它。下面的程序就是一个这种尝试:

//: C04:FileClass.h

// stdio files wrapped.

#ifndef FILECLASS_H

#define FILECLASS_H

#include <cstdio>

#include <stdexcept>

class FileClass {

  std::FILE* f;

public:

  struct FileClassError : std::runtime_error {

    FileClassError(const char* msg)

    : std::runtime_error(msg) {}

  };

  FileClass(const char* fname, const char* mode = "r");

  ~FileClass();

  std::FILE* fp();

};

#endif // FILECLASS_H ///:~

 当你在C中进行文件的IO操作时,你用的是一个指向FILE结构的裸指针。但是这个类在该指针上包装了一层,使用构造函数和析构函数保证它被正确的初始化和清除。第二个构造函数的参数是文件的打开模式,缺省为’r’(read)

 

为了在文件IO函数中获取该指针的值,你得使用fp( )来访问函数。这儿是成员函数定义:

//: C04:FileClass.cpp {O}

// FileClass Implementation.

#include "FileClass.h"

#include <cstdlib>

#include <cstdio>

using namespace std;

FileClass::FileClass(const char* fname, const char* mode) {

  if((f = fopen(fname, mode)) == 0)

    throw FileClassError("Error opening file");

}

FileClass::~FileClass() { fclose(f); }

FILE* FileClass::fp() { return f; } ///:~

正如你通常所做的,构造函数调用fopen( ),但是它也保证了结果不是0,是0就预示着打开文件失败了。如果文件不能按希望的打开,一个异常就会抛出。

 

析构函数关闭文件,访问函数返回f。这儿是使用FileClass的一个简单例子:

 //: C04:FileClassTest.cpp

//{L} FileClass

#include <cstdlib>

#include <iostream>

#include "FileClass.h"

using namespace std; 

int main() {

  try {

    FileClass f("FileClassTest.cpp");

    const int BSIZE = 100;

    char buf[BSIZE];

    while(fgets(buf, BSIZE, f.fp()))

      fputs(buf, stdout);

  } catch(FileClass::FileClassError& e) {

    cout << e.what() << endl;

    return EXIT_FAILURE;

  }

  return EXIT_SUCCESS;

} // File automatically closed by destructor

///:~

你创建了FileClass对象,并且通过调用fp( )用通常的C文件 I/O调用方式来使用它。当你把它处理完了,就忘记她吧。在作用域末尾析构函数会将文件关闭。

 

  如果您要在各种媒体刊载、引用本文档,请不要对本文档内容进行任何修改。作为学习和交流目的,本文档的使用是免费的,如果您直接或间接将本文档用于商业用途,请在使用前与我联系,获得同意后方可使用。否则,一切后果自负!本文档的英文原文可以在bruceeckel的网站(www.BruceEkel.com)上找到。让我们对bruceeckel的开源精神致以崇高的敬意。

Bruce Eckel 《Thinking in Java》(Java编程思想)作者。Eckel有20年专业编程经验,并自1986年起教育人们如何撰写面向对象程序,足迹遍及全球,成为一位知名的 C++教师和顾问,如今兼涉Java。他是C++标准委员会拥有表决权的成员之一,曾经写过另五本面向对象编程书籍,发表过150篇以上的文章,是多本计算机杂志的专栏作家。Eckel开创Software Development Conference的C++、Java、Python等多项研讨活动。拥有应用物理学学士和计算机工程学硕士学位。 目录 译者序 前言 第1章 对象导言 第2章 对象的创建与使用 第3章 C++中的C 第4章 数据抽象 第5章 隐藏实现 第6章 初始化与清除 第7章 函数重载与默认参数 第8章 常量 第9章 内联函数 第10章 名字控制 第11章 引用和拷贝构造函数 第12章 运算符重载 第13章 动态对象创建 第14章 继承和组合 第15章 多态性和虚函数 第16章 模板介绍 附录A 编码风格 附录B 编程准则 附录C 推荐读物 索引 第2:实用编程技术 出版者的话 专家指导委员会 译者序 前言 第一部分 建立稳定的系统 第1章 异常处理 第2章 防御性编程 第二部分 标准C++库 第3章 深入理解字符串 第4章 输入输出流 第5章 深入理解模板 第6章 通用算法 第7章 通用容器 第三部分 专题 第8章 运行时类型识别 第9章 多重继承 第10章 设计模式 第11章 并发 附录 附录A 推荐读物 附录B 其他 索引 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值