|
Программирование >> Оптимизация возвращаемого значения
продолжить обычное создание объекта; ++numObjects ; Printer * Printer::makePrinter() { return new Printer; } Если требование того, что при попытке создания слишком большого числа объектов надо генерировать исключение, кажется вам чрезвычайно строгим, вы можете вместо этого возвращать в псевдоконструкторе нулевой указатель. Конечно, тогда клиентам придется проверять указатель перед тем, как работать с ним. Клиенты используют класс Printer так же, как и любой другой, только вместо настоящего конструктора они должны вызывать псевдоконструктор: Printer р1; Ошибка! конструктор по умолчанию - закрытый. Printer *р2 = Printer::makePrinter(); Нормально, косвенно вызывает конструктор по умолчанию. Printer рЗ = *р2; Ошибка! конструктор копирования - закрытый. p2->performSelfTest{); Все остальные функции p2->reset{); вызываются как обычно. delete р2; Надо, чтобы избежать утечки ресурсов; не нужно, если указатель р2 имеет тип auto ptr. Этот метод применим к любому числу объектов. Вы должны только заменить постоянную 1 на нужное значение, а затем снять запрет на копирование объектов. Например, следующая реализация класса Printer допускает существование до 10 объектов Printer: class Printer { public: class TooManyObj ectsO; Псевдоконструкторы. static Printer * makePrinter{); static Printer * makePrinter(const Printers rhs) ; private: static size t numObjects; static const size t maxObjects =10; См. ниже. Printer О; Printer(const Printers rhs); Обязательное объявление статических объектов класса. size t Printer::numObjects = 0; const size t Printer::maxobjects; Printer::Printer{) if (numObjects >= maxObjects) { throw TooManyObj ects () ; Printer::Printer(const Printers rhs) { if (numObjects >= maxObjects) { throw TooManyObj ects () ; Printer * Printer::makePrinter() { return new Printer; } Printer * Printer::makePrinter(const Printers rhs) { return new Printer (rhs) ; } He удивляйтесь, если объявление Printer: :maxObjects в определении этого класса компиляторы не примут. В особенности если они будут сообщать об ошибке при присвоении переменной начального значения 10. Возможность присваивать начальные значения статическим элементам, объявленным как const (целочисленных типов, например int, char, enum и т.д.) внутри определения класса была добавлена в язык С++ сравнительно недавно, поэтому некоторые компиляторы еще не позволяют этого. Если ваши компиляторы относятся к ним, вы можете объявить maxObjects как счетчик в закрытом неименованном перечисляемом типе: class Printer { private: enum { maxObjects = 10 }; В этом классе ... maxObjects - постоянная, }; равная 10. ИЛИ при помощи инициализации постоянного статического объекта как статического элемента не const: class Printer { private: static const size t maxObjects; He задано начальное значение. Это находится в отдельном файле реализации, const size t Printer::maxObjects = 10; Последний способ действует так же, как и вышеприведенный исходный код, но явное определение начального значения облегчает понимание кода другими программистами. Если ваши компиляторы поддерживают задание начального значения для статических const элементов в определении класса, вы должны использовать эту возможность. Базовый класс для подсчета объектов У вышеописанного метода есть один негативный аспект. Если существует множество классов, подобных классу Printer, число экземпляров которых требуется ограничивать, то вам придется писать один и тот же код снова и снова для каждого из классов. В таком шикарном языке, как C-i-i-, должен быть способ автоматизировать этот процесс. Как же инкапсулировать понятие подсчета числа экземпляров и заключить его в класс? Это легко сделать, создав базовый класс для подсчета числа экземпляров объекта и сделать такие классы, как Printer, его наследниками, но, оказывается, есть лучшее решение. Можно разработать способ инкапсуляции всего набора для подсчета, под которым я подразумеваю не только функции, управляющие подсчетом экземпляров, но и сам алгоритм подсчета экземпляров. (Вы увидите необходимость аналогичного приема при рассмотрении счетчика ссылок в правиле 29.) В классе Printer счетчиком является статическая переменная NumObj ects, поэтому вам нужно поместить эту переменную в класс счетчика экземпляров. Вы должны быть также уверены, что каждый из классов, число экземпляров которых подсчитывается, имеет отдельный счетчик. Применение шаблона класса счетчика позволяет автоматически создавать соответствующее число счетчиков: можно сделать счетчик статическим элементом классов, образованных на основе этого шаблона: template<class BeingCounted> class Counted { public: class TooManyObjects{}; Для генерации исключений, static int objectCount {) { return numObjects; } protected: Counted 0; Counted(const Counted& rhs) ; -CountedO { -numObjects; } private: static int numObjects; static const size t maxObjects; void initO ; Чтобы избежать дублирования }; / / кода конструктора. template<class BeingCounted> Counted<BeingCounted>::Counted() { initO ; } template<class BeingCounted> Counted<BeingCounted>::Counted(const Counted<BeingCounted>&) { init(); }
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |