Читаем Thinking In C++. Volume 2: Practical Programming полностью

Even though the FILE pointer is private, it isn’t particularly safe because fp( ) retrieves it. Since the only effect seems to be guaranteed initialization and cleanup, why not make it public or use a struct instead? Notice that while you can get a copy of f using fp( ), you cannot assign to f— that’s completely under the control of the class. Of course, after capturing the pointer returned by fp( ), the client programmer can still assign to the structure elements or even close it, so the safety is in guaranteeing a valid FILE pointer rather than proper contents of the structure.

If you want complete safety, you must prevent the user from directly accessing the FILE pointer. Some version of all the normal file I/O functions must show up as class members so that everything you can do with the C approach is available in the C++ class:.

//: C04:Fullwrap.h

// Completely hidden file IO

#ifndef FULLWRAP_H

#define FULLWRAP_H

class File {

  std::FILE* f;

  std::FILE* F(); // Produces checked pointer to f

public:

  File(); // Create object but don't open file

  File(const char* path,

       const char* mode = "r");

  ~File();

  int open(const char* path,

           const char* mode = "r");

  int reopen(const char* path,

             const char* mode);

  int getc();

  int ungetc(int c);

  int putc(int c);

  int puts(const char* s);

  char* gets(char* s, int n);

  int printf(const char* format, ...);

  size_t read(void* ptr, size_t size,

              size_t n);

  size_t write(const void* ptr,

size_t size, size_t n);

  int eof();

  int close();

  int flush();

  int seek(long offset, int whence);

  int getpos(fpos_t* pos);

  int setpos(const fpos_t* pos);

  long tell();

  void rewind();

  void setbuf(char* buf);

  int setvbuf(char* buf, int type, size_t sz);

  int error();

  void clearErr();

};

#endif // FULLWRAP_H ///:~

This class contains almost all the file I/O functions from . (vfprintf( ) is missing; it is used to implement the printf( ) member function.).

File has the same constructor as in the previous example, and it also has a default constructor. The default constructor is important if you want to create an array of File objects or use a File object as a member of another class in which the initialization doesn’t happen in the constructor, but some time after the enclosing object is created.

The default constructor sets the private FILE pointer f to zero. But now, before any reference to f, its value must be checked to ensure it isn’t zero. This is accomplished with F( ), which is private because it is intended to be used only by other member functions. (We don’t want to give the user direct access to the underlying FILE structure in this class.)[38] 

This approach is not a terrible solution by any means. It’s quite functional, and you could imagine making similar classes for standard (console) I/O and for in-core formatting (reading/writing a piece of memory rather than a file or the console).

The big stumbling block is the runtime interpreter used for the variable argument list functions. This is the code that parses your format string at runtime and grabs and interprets arguments from the variable argument list. It’s a problem for four reasons.

1.Even if you use only a fraction of the functionality of the interpreter, the whole thing gets loaded into your executable. So if you say printf("%c", 'x');, you’ll get the whole package, including the parts that print floating-point numbers and strings. There’s no standard option for reducing the amount of space used by the program.

2.Because the interpretation happens at runtime, you can’t get rid of a performance overhead. It’s frustrating because all the information is there in the format string at compile time, but it’s not evaluated until runtime. However, if you could parse the arguments in the format string at compile time, you could make direct function calls that have the potential to be much faster than a runtime interpreter (although the printf( ) family of functions is usually quite well optimized).

3.A worse problem is that the format string is not evaluated until runtime: there can be no compile-time error checking. You’re probably familiar with this problem if you’ve tried to find bugs that came from using the wrong number or type of arguments in a printf( ) statement. C++ makes a big deal out of compile-time error checking to find errors early and make your life easier. It seems a shame to throw type safety away for an I/O library, especially because I/O is used a lot.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных