Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Исключения и профилактика утечек памяти. 
:(
    Опции темы
borisbn
Дата 11.4.2012, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(makavelly @  10.4.2012,  18:18 Найти цитируемый пост)
 чревато ли возвращать адрес локальной переменной (меня это очень смущает)

Это должно не "смущать", а "орать благим матом", что такого делать нельзя. Хоть в dll-ке, хоть в исходниках.
Есть сразу несколько вариантов:
1) вернуть структуру по значению
Код

MyResultA DoSomethingA(...) {
    MyResultA ret = {0,0};

    return ret;
}
// вызов
MyResultA res = DoSomethingA(...);

2) Передать в функцию ссылку на структуру и заполнить её внутри функции (я бы выбрал этот вариант) :
Код

void DoSomethingA( MyResultA & result ) {

    result.resultCode = ...;
    result.elapsedTime = ...;
}
// вызов
MyResultA res;
DoSomethingA( res );

3) обойтись вообще без структуры:
Код

int DoSomethingA( int & elapsedTime ) {

    elapsedTime = ...;
    return код результата;
}

// вызов
int elapsedTime;
int resultCode = DoSomethingA( elapsedTime );



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 11.4.2012, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(makavelly @  10.4.2012,  17:18 Найти цитируемый пост)
: чревато ли возвращать адрес локальной переменной


а возмущениям компилятора не верите ?!


--------------------
PM MAIL WWW   Вверх
makavelly
Дата 12.4.2012, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



borisbn, да, вариант #2 - самое оно. 
Еще один вопрос сформировался у меня. В C# есть очень удобные классы BinaryWriter, MemoryStream, FileStream и пр., при помощи которых легко и просто осуществляется ввод\вывод, работа с данными в памяти. Есть ли в C++ что-либо похожее на MemoryStream? Может какие-нибудь легковесные библиотеки?
PM MAIL   Вверх
ller
Дата 12.4.2012, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

Репутация: 2
Всего: 4



есть std::stringstream потоковый ввод вывод из/в строки
PM MAIL   Вверх
makavelly
Дата 13.4.2012, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Хотелось бы еще уточнить по поводу передачи ссылки на экземпляр класса как параметр функции. 

Если передать следующим образом:
Код

void MyFunc(MyClass val)
{
    ...
}

то что передастся в функцию? Копия экземпляра?

Если передавать вот так:
Код

void MyFunc(MyClass & val)
{
    ...
}

то, как я понимаю, я получаю доступ к экземпляру по ссылке.

А если вот так:
Код

void MyFunc(const MyClass & val){   ...  }

или так:
Код

void MyFunc(const MyClass val){  ...  }

Какие здесь работают правила? 
Может быть кто-нибудь знает ссылку на толковую статью по теме?
PM MAIL   Вверх
borisbn
Дата 13.4.2012, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(makavelly @  13.4.2012,  17:00 Найти цитируемый пост)
то что передастся в функцию? Копия экземпляра?

да
Цитата(makavelly @  13.4.2012,  17:00 Найти цитируемый пост)
то, как я понимаю, я получаю доступ к экземпляру по ссылке.

можно сказать, что в этом случае val будет являться "алиасом" того экземпляра, который будет передан в функцию
Код

MyClass someObj;
void MyFunc( MyClass & val ) {
    val.field = 0; // идентично тому, что написать someObj.field = 0; 
            // при условии, что вызов будет такой MyFunc( someObj );
}


Цитата(makavelly @  13.4.2012,  17:00 Найти цитируемый пост)
А если вот так:
Код
void MyFunc(const MyClass & val){   ...  }

val тоже будет являться "алиасом", но в него нельзя будет ничего записать и вызывать можно будет только функции класса MyClass, помеченные как const

Цитата(makavelly @  13.4.2012,  17:00 Найти цитируемый пост)
или так:
Код
void MyFunc(const MyClass val){  ...  }

В это случае будет передана копия экземпляра, у которой также нельзя будет ничего записать и вызывать можно будет только функции класса MyClass, помеченные как const


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
makavelly
Дата 13.4.2012, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Т.е. в общих чертах получается: если надо просто извлечь данные из экземпляра класса, то
Код

void MyFunc(const MyClass & val){  ...  }

Если надо изменить передаваемый объект, то
Код

void MyFunc(MyClass & val){  ...  }

Спасибо за ответы, хорошо, когда есть у кого уточнить=)
PM MAIL   Вверх
makavelly
Дата 16.4.2012, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Хотелось бы еще поинтересоваться по поводу исключений. Есть класс, который будет содержать данные исключения (например код ошибки, человеческое описание, что-либо еще). Как я понимаю возбуждать такое исключение надо так:
Код

void ThrowException( ... )
{
    throw MyExceptionClass( ... );
}

А ловить как-то так:
Код

try
{
    // something dangerous
}
catch (MyExceptionClass ex)
{
    // processing according ex data...
}

Когда объект исключения будет уничтожен? Я полагаю, что после выхода из
Код

catch (MyExceptionClass ex)
{
    // processing according ex data...
}

Верно? Т.е., если объект исключения предоставляет доступ к тексту ошибки через указатель на char, я должен скопировать данные с этого указателя в блоке catch (MyExceptionClass ex) { ... } ?
PM MAIL   Вверх
azesmcar
Дата 16.4.2012, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(makavelly @  16.4.2012,  17:12 Найти цитируемый пост)
А ловить как-то так:

Как-то, но не так smile 

Цитата

catch (MyExceptionClass& ex)

исключения лучше ловить по ссылке.

Цитата(makavelly @  16.4.2012,  17:12 Найти цитируемый пост)
Когда объект исключения будет уничтожен?

Цитата

The memory for the temporary copy of the exception being thrown is allocated in an unspecified way,
except as noted in 3.7.3.1. The temporary persists as long as there is a handler being executed for that
exception. In particular, if a handler exits by executing a throw; statement, that passes control to another
handler for the same exception, so the temporary remains. When the last handler being executed for the
exception exits by any means other than throw; the temporary object is destroyed and the implementation
may deallocate the memory for the temporary object; any such deallocation is done in an unspecified way.
The destruction occurs immediately after the destruction of the object declared in the exception-declaration
in the handler.


Это сообщение отредактировал(а) azesmcar - 16.4.2012, 18:34
PM   Вверх
baldina
Дата 16.4.2012, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



ловить лучше ссылку
Код

catch (MyExceptionClass& ex)

во избежание лишнего копирования
жить будет до окончания блока catch, так что внутри него можно спокойно пользоваться объектом.

Добавлено через 2 минуты и 5 секунд
azesmcar уже ответил...
ну тогда вот краткая иллюстрация
http://codepad.org/oqkk0CiV
PM MAIL   Вверх
borisbn
Дата 16.4.2012, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



makavelly, это всё довольно просто проверяется - http://liveworkspace.org/code/cde774c60990...0b02c871181bb3b
кстати, пока изучаешь, вози этот классик для всяческих проверок... если пишешь на MSVC, то замени все __PRETTY_FUNCTION__ на __FUNCSIG__


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
makavelly
Дата 19.4.2012, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



До этого достаточно долго работал с Delphi, все там как-то проще, труднее ошибиться. Это так, к слову.
Сейчас добрался до реализации класса, хочеться сделать все грамотно. 

Вот первый вопрос. Есть класс который, например, пишет данные в файл. Пусть этот класс предоставляет данные о версии файлов, генерируемых с его помощью. Например:
Код

class MyExporter
{
private:
    static const unsigned int myFileMajorVersion = 1;
    static const unsigned int myFileMinorVersion = 0;

              static void ThrowException();

public:
    static unsigned int GetFileMajorVersion();
    static unsigned int GetFileMinorVersion();

};

Верно ли, что функции GetFileMajorVersion() и GetFileMinorVersion() я объявляю как static? Ведь, по идее, их можно вызывать без создания экземпляра класса. Есть ли смысл делать функцию ThrowException() тоже static?

Еще вопрос. Иногда функции помечаются как const, типа
Код

void DoSomething() const;

В каких случаях принято использовать такие пометки? Когда действия внутри функции не затрагивают переменных класса? Какое тогда отличие от static?


PM MAIL   Вверх
borisbn
Дата 20.4.2012, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(makavelly @  19.4.2012,  18:34 Найти цитируемый пост)
Верно ли, что функции GetFileMajorVersion() и GetFileMinorVersion() я объявляю как static?

 smile 

Цитата(makavelly @  19.4.2012,  18:34 Найти цитируемый пост)
Ведь, по идее, их можно вызывать без создания экземпляра класса. 

И правильно. Зачем создавать экземпляр класса, чтобы узнать о его версии

Цитата(makavelly @  19.4.2012,  18:34 Найти цитируемый пост)
В каких случаях принято использовать такие пометки? Когда действия внутри функции не затрагивают переменных класса? Какое тогда отличие от static?

Действия const'овой функции не могут изменять переменные класса, а читать их они могут. Также const'овая функция не может вызывать не-const'овые методы класса, потому что здесь не действует презумпция невиновности - даже если эти методы ничего не изменяют, но не помечены как const, считается, что они "виновны" )) Поэтому, если ты видишь, что твой метод ничего не изменяет в классе (и не вызывает других не-const'овых методов), то смело помечай его невиновным - aka const'овым, чтобы его можно было позвать из таких-же невиновных функций.

static же функции не имеют доступа к членам и методам класса. Они практически не отличаются от обычных функций вне класса.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
makavelly
Дата 20.4.2012, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Цитата

Действия const'овой функции не могут изменять переменные класса, а читать их они могут.

Если переменные простых типов (int, unsigned int ...), то понятно. А если, например, в качестве переменной выступает указатель на экземпляр класса. Из такой функции нельзя произвести действия, изменяющие что-либо в этом экземпляре? Вот заставить такой указатель указывать на что-либо иное из такой ф-ции, как понимаю, нельзя.

А есть смысл помечать как static функции вне классов? Я, кажется, подобное видел, хотя могу и ошибаться. 

PM MAIL   Вверх
borisbn
Дата 20.4.2012, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(makavelly @  20.4.2012,  11:42 Найти цитируемый пост)
 Из такой функции нельзя произвести действия, изменяющие что-либо в этом экземпляре?

 smile 
Т.е. опять же, можно вызывать только const'овые методы того ("дочернего") класса. И читать открытые свойства.

Цитата(makavelly @  20.4.2012,  11:42 Найти цитируемый пост)
А есть смысл помечать как static функции вне классов?

у свободных функций (вне класса) пометка static значит совсем иное - это говорит о том, что эта функция видна только в этой единице трансляции (в этом cpp-шнике), и сделать на неё extern из другого cpp-шника нельзя.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1389 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.