Private-Bookers
C++. Сборник рецептов
вернуться

Когсуэлл Джефф

Шрифт:

Если вы пишете функцию или метод, создающий объекты, то посмотрите также рецепт 8.12. Используя шаблоны, функций можно написать одну функцию, которая будет возвращать новый объект любого типа. Например:

template<typename T>

T* createObject {

 return(new T);

}

MyClass* p1 = createObject;

MyOtherClass* p2 = createObject;

// ...

Этот подход удобен, если требуется единственная функция фабрики, которая сможет одинаковым образом создавать объекты любых классов (или группы связанных классов), что позволит избежать избыточного многократного кодирования функции фабрики.

Смотри также

Рецепт 8.12.

8.3. Использование конструкторов и деструкторов для управления ресурсами (RAII)

Проблема

Для класса, представляющего некоторый ресурс, требуется использовать конструктор для получения этого ресурса и деструктор для его освобождения. Эта методика часто называется «получение ресурсов как инициализация» (resource acquisition is initialization — RAII).

Решение

Выделите или получите ресурс в конструкторе и освободите этот ресурс в деструкторе. Это снизит объем кода, который пользователь класса должен будет написать для обработки исключений. Простая иллюстрация этой методики показана в примере 8.3.

Пример 8.3. Использование конструкторов и деструкторов

#include <iostream>

#include <string>

using namespace std;

class Socket {

public:

 Socket(const string& hostname) {}

};

class HttpRequest {

public:

 HttpRequest(const string& hostname) :

sock_(new Socket(hostname)) {}

 void send(string soapMsg) {sock << soapMsg;}

 ~HttpRequest {delete sock_;}

private:

 Socket* sock_;

};

void sendMyData(string soapMsg, string host) {

 HttpRequest req(host);

 req.send(soapMsg);

 // Здесь делать ничего не требуется, так как когда req выходит

 // за диапазон, все очищается.

}

int main {

 string s = "xml";

 sendMyData(s, "www.oreilly.com");

}

Обсуждение

Гарантии, даваемые конструкторами и деструкторами, представляют собой удобный способ заставить компьютер выполнить всю очистку за вас. Обычно инициализация объекта и выделение используемых ресурсов производится в конструкторе, а очистка — в деструкторе. Это нормально. Но программисты имеют склонность использовать последовательность событий «создание-открытие-использование-закрытие», когда пользователю класса требуется выполнять явные открытия и закрытия ресурсов. Класс файла является хорошим примером.

Примерно так звучит обычный аргумент в пользу RAII. Я легко мог бы создать в примере 8.3 свой класс

HttpRequest
, который заставил бы пользователя выполнить несколько больше работы. Например:

class HttpRequest {

public:

 HttpRequest;

 void open(const std::string& hostname);

 void send(std::string soapMsg);

 void close;

 ~HttpRequest;

private:

 Socket* sock_;

};

При таком подходе соответствующая версия

sendMyData
может выглядеть так.

void sendMyData(std::string soapMsg, std::string host) {

 HttpRequest req;

 try {

req.open;

req.send(soapMsg);

req.close;

 } catch (std::exception& e) {

req.close; // Do something useful...

  • Читать дальше
  • 1
  • ...
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • ...

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка