![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
makavelly |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
На c++ не пишу, но возникла необходимость. Допустим, есть такой код:
Как я понимаю, при возникновении исключительной ситуации (5-я строка), подчистить за собой не получится. Как обычно в c++ решают такие ситуации? Например, в Delphi это можно оформить как try - finally - end. Разместив удаление объекта в finally ... end можно получить почти 100% гарантию уничтожения объекта. И еще вопрос... Есть ли в MS VC Express 2008 какой-нибудь механизм, позволяющий отслеживать утечки памяти? |
|||
|
||||
Amp |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 886 Регистрация: 17.2.2009 Репутация: нет Всего: 17 |
Создать объект на стэке, использовать умные указатели, измазать код в BOOST_SCOPE_EXIT/BOOST_SCOPE_EXIT_END и т.п.
|
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
RAII. тогда код записывается так:
|
|||
|
||||
makavelly |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Я наслышан о boost - массивный инструмент, можно обойтись без него?
Почитал про RAII, возникло несколько вопросов. C++ поддерживает этот принцип? Хотелось бы еще уточнить по поводу области видимости. Пример функции (видел нечто подобное в чужом коде):
Получается, что когда заканчивается выполнение DoSomeProcessing() importer выходит из области видимости и ресурсы будут освобождены? Если эта функция будет вызвана повторно, мы будем иметь дело с новым объектом importer? А если DoSomeProcessing() будет принадлежать классу? Вопросы, конечно, кажутся наивными, но как по мне, C++ коварен. |
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Поддерживает. Из стандартных средств можно использовать std::auto_ptr применительно к данной ситуации shared_ptr - overkill ![]() Да. Без разницы. Это сообщение отредактировал(а) azesmcar - 9.4.2012, 21:08 |
|||
|
||||
makavelly |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Благодарю за ответы, ситуация начинает понемногу проясняться.
Еще один вопрос. Допустим, я хочу, что бы объект класса MyImporter являлся членом моего класса, который осуществляет некоторые действия над ним. Я хочу, чтобы экземпляр MyImporter'a существовал все время жизни экземпляра класса-обертки. Как я понимаю, для этого следует прописать такое объявление в объявлении класса-обертки
В конструкторе:
В деструкторе:
|
||||||
|
|||||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
makavelly
Можно и так
|
|||
|
||||
makavelly |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Т.е. получается, сам факт объявления в классе
уже создает объект importer... и как я догадываюсь, во время создания экземпляра класса X. Следует ли отсюда, что при уничтожении экземпляра класса X автоматически будут освобождены ресурсы, выделенные под importer? |
||||||
|
|||||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
||||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
ну да. скопеда достаточно. |
|||
|
||||
borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
makavelly, и ещё один момент. Если в заголовочный файл класса-обёртки включить объект MyImporter, а не указатель на него
то в этот же заголовочный файл придётся включить и h-ник с объявлением MyImporter (например "importer.h"). При включении h-ника класса-обёртки в нескольких cpp-шниках "importer.h" будет компилироваться несколько раз, что увеличивает время компиляции. Если же ты включишь в класс-обёртку указатель, то "importer.h" достаточно включить только в cpp-нике класса обёртки, а в h-нике предобъявить MyImporter
Это сообщение отредактировал(а) borisbn - 10.4.2012, 06:42 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
makavelly |
|
||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
borisbn, я видел вот такую конструкцию в *.h:
Может это для таких случаев Хотелось бы еще уточнить. В некоторых исходниках можно встретить подобные объявления:
Достаточно часто такое встречается. Какая смысловая нагрузка у префикса "m"? |
||||
|
|||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Это для того, чтобы при множественном включении заголовочного файла не возникало ошибок компиляции. Еще часто используется #pragma once, который не стандартен, но тем не менее поддерживается очень многими компиляторами.
Указывает на то, что это member variable. Это так называемая венгерская нотация. Это сообщение отредактировал(а) azesmcar - 10.4.2012, 10:56 |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
нет. если h-ник включен в двух разных единицах трансляции (проще - в 2-х cpp-шниках), то он будет компилироваться дважды, несмотря на эти, т.н. guard'ы. А эти guird'ы нужны, чтобы в такой ситуации
код из 1.h не повторялся. иначе получится 2 описания класса X. member of class -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
makavelly |
|
||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Еще один вопрос. Прект - dll. Есть экспортируемая функция, запускающая обработку некоторых данных. Необходимо вернуть из этой функции результат в виде кода ошибки (или ее отсутствия) и времени выполнения обработки. Т.е. получается что надо вернуть адрес структуры типа:
Вопрос: чревато ли возвращать адрес локальной переменной (меня это очень смущает)? Например:
|
||||
|
|||||
borisbn |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
Это должно не "смущать", а "орать благим матом", что такого делать нельзя. Хоть в dll-ке, хоть в исходниках. Есть сразу несколько вариантов: 1) вернуть структуру по значению
2) Передать в функцию ссылку на структуру и заполнить её внутри функции (я бы выбрал этот вариант) :
3) обойтись вообще без структуры:
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||||||
|
|||||||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
а возмущениям компилятора не верите ?! |
|||
|
||||
makavelly |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
borisbn, да, вариант #2 - самое оно.
Еще один вопрос сформировался у меня. В C# есть очень удобные классы BinaryWriter, MemoryStream, FileStream и пр., при помощи которых легко и просто осуществляется ввод\вывод, работа с данными в памяти. Есть ли в C++ что-либо похожее на MemoryStream? Может какие-нибудь легковесные библиотеки? |
|||
|
||||
ller |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 4.8.2008 Где: г. Таганрог Репутация: 2 Всего: 4 |
есть std::stringstream потоковый ввод вывод из/в строки
|
|||
|
||||
makavelly |
|
||||||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Хотелось бы еще уточнить по поводу передачи ссылки на экземпляр класса как параметр функции.
Если передать следующим образом:
то что передастся в функцию? Копия экземпляра? Если передавать вот так:
то, как я понимаю, я получаю доступ к экземпляру по ссылке. А если вот так:
или так:
Какие здесь работают правила? Может быть кто-нибудь знает ссылку на толковую статью по теме? |
||||||||
|
|||||||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
да можно сказать, что в этом случае val будет являться "алиасом" того экземпляра, который будет передан в функцию
val тоже будет являться "алиасом", но в него нельзя будет ничего записать и вызывать можно будет только функции класса MyClass, помеченные как const В это случае будет передана копия экземпляра, у которой также нельзя будет ничего записать и вызывать можно будет только функции класса MyClass, помеченные как const -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
makavelly |
|
||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Т.е. в общих чертах получается: если надо просто извлечь данные из экземпляра класса, то
Если надо изменить передаваемый объект, то
Спасибо за ответы, хорошо, когда есть у кого уточнить=) |
||||
|
|||||
makavelly |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Хотелось бы еще поинтересоваться по поводу исключений. Есть класс, который будет содержать данные исключения (например код ошибки, человеческое описание, что-либо еще). Как я понимаю возбуждать такое исключение надо так:
А ловить как-то так:
Когда объект исключения будет уничтожен? Я полагаю, что после выхода из
Верно? Т.е., если объект исключения предоставляет доступ к тексту ошибки через указатель на char, я должен скопировать данные с этого указателя в блоке catch (MyExceptionClass ex) { ... } ? |
||||||
|
|||||||
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Как-то, но не так ![]()
исключения лучше ловить по ссылке.
Это сообщение отредактировал(а) azesmcar - 16.4.2012, 18:34 |
||||
|
|||||
baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 15 Всего: 101 |
ловить лучше ссылку
во избежание лишнего копирования жить будет до окончания блока catch, так что внутри него можно спокойно пользоваться объектом. Добавлено через 2 минуты и 5 секунд azesmcar уже ответил... ну тогда вот краткая иллюстрация http://codepad.org/oqkk0CiV |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
makavelly, это всё довольно просто проверяется - http://liveworkspace.org/code/cde774c60990...0b02c871181bb3b
кстати, пока изучаешь, вози этот классик для всяческих проверок... если пишешь на MSVC, то замени все __PRETTY_FUNCTION__ на __FUNCSIG__ -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
makavelly |
|
||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
До этого достаточно долго работал с Delphi, все там как-то проще, труднее ошибиться. Это так, к слову.
Сейчас добрался до реализации класса, хочеться сделать все грамотно. Вот первый вопрос. Есть класс который, например, пишет данные в файл. Пусть этот класс предоставляет данные о версии файлов, генерируемых с его помощью. Например:
Верно ли, что функции GetFileMajorVersion() и GetFileMinorVersion() я объявляю как static? Ведь, по идее, их можно вызывать без создания экземпляра класса. Есть ли смысл делать функцию ThrowException() тоже static? Еще вопрос. Иногда функции помечаются как const, типа
В каких случаях принято использовать такие пометки? Когда действия внутри функции не затрагивают переменных класса? Какое тогда отличие от static? |
||||
|
|||||
borisbn |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
![]()
И правильно. Зачем создавать экземпляр класса, чтобы узнать о его версии
Действия const'овой функции не могут изменять переменные класса, а читать их они могут. Также const'овая функция не может вызывать не-const'овые методы класса, потому что здесь не действует презумпция невиновности - даже если эти методы ничего не изменяют, но не помечены как const, считается, что они "виновны" )) Поэтому, если ты видишь, что твой метод ничего не изменяет в классе (и не вызывает других не-const'овых методов), то смело помечай его невиновным - aka const'овым, чтобы его можно было позвать из таких-же невиновных функций. static же функции не имеют доступа к членам и методам класса. Они практически не отличаются от обычных функций вне класса. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||||
|
|||||||
makavelly |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 26.3.2008 Репутация: нет Всего: нет |
Если переменные простых типов (int, unsigned int ...), то понятно. А если, например, в качестве переменной выступает указатель на экземпляр класса. Из такой функции нельзя произвести действия, изменяющие что-либо в этом экземпляре? Вот заставить такой указатель указывать на что-либо иное из такой ф-ции, как понимаю, нельзя. А есть смысл помечать как static функции вне классов? Я, кажется, подобное видел, хотя могу и ошибаться. |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
![]() Т.е. опять же, можно вызывать только const'овые методы того ("дочернего") класса. И читать открытые свойства. у свободных функций (вне класса) пометка static значит совсем иное - это говорит о том, что эта функция видна только в этой единице трансляции (в этом cpp-шнике), и сделать на неё extern из другого cpp-шника нельзя. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |