crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Оператор new
haiflive
  опции профиля:
сообщение 9.7.2011, 15:52
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 37
Регистрация: 8.7.2010
Пользователь №: 1868

Спасибо сказали: 1 раз(а)




Репутация:   0  


Прошу разъяснить мне давно волнующую меня тему..
Вопрос про оператор new, в чём разница между этими двумя функциями?. какой вариант предпочтительней и почему?.

Функция 1:
void myFunction()
{
    myObject* obj = new myObject;
    /*...*/
    delete obj;
}


Функция 2:
void myFunction2()
{
    myObject obj;
    /*...*/
}


Я конечно понимаю, что выделение памяти произодёт в первом варианте в момент создания обекта, а во втором в момент обращения к функции.. А ни всё ли равно?. ну конечно если мы там внутри функции будем работать с "большим обектом", то его возможно потребуется удалить(и создать и удалить), НО рассматривается тот случай, когда создаётся объект в начале функции и удаляется только в конце..
Насчёт скорости ничего сказать не могу..
Насчёт ошибок, второй вариант предпочтительней так как по объёму написанного кода меньше, и не надо думать о том, что бы удалять обект.
Почему я сплошь и рядом наблюдаю первый вариант?. это что такая привычка, или есть скрытый смысл?.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 9.7.2011, 16:52
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


первое - создание переменной в куче, второе - на стеке. Куча - "неудобная, но резиновая", стек - "удобный, не резиновый". Хотя, всё зависит от опыта использования )

>>Почему я сплошь и рядом наблюдаю первый вариант?
покажи пример
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 9.7.2011, 22:44
Сообщение #3


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


сейчас напрямую выделение динамических объектов в памяти используется не так часто.
когда объектов много - то проще юзать различные "умные" указатели, за которыми не нужно следить, или пулы переменных, в которых "выделение" и "освобождение" памяти происходит куда быстрее, чем множественными вызовами для каждого элемента.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 9.7.2011, 23:02
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(haiflive @ 9.7.2011, 18:52) *
А ни всё ли равно?
нет, т.к. во-втором случае, как только выйдешь из функции - объект умрёт, а в-первом случае - останется жить. И, если ты сохранишь указатель на объект в-первом случае, то сможешь к этому объекту обращаться в будущем.

Цитата(haiflive @ 9.7.2011, 18:52) *
Насчёт скорости ничего сказать не могу..
объекты созданные на стеке (второй вариант), создаются "сразу", скорость дальнейшей их работы одинакова с первым вариантом.

Цитата(haiflive @ 9.7.2011, 18:52) *
Почему я сплошь и рядом наблюдаю первый вариант?
Если для примера взять Qt и его QObject, то в этом классе не предусмотрены операторы присваивания и конструкторы копирования, т.к. это не тривиальные операции для данного (навороченого) класса и его наследников. Это и является причиной создания объектов в куче и работа с ними через указатель.

П.С.
По-этому всюду в функциях библиотеки предусмотрен в качестве входного аргумента указатель на QObject.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
haiflive
  опции профиля:
сообщение 10.7.2011, 6:57
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 37
Регистрация: 8.7.2010
Пользователь №: 1868

Спасибо сказали: 1 раз(а)




Репутация:   0  


Спасибо всем за исчерпывающие ответы.

Цитата
стек - "удобный, не резиновый"

Насколько он не резиновый?. или это зависит от компилятора?. Компилятор MinGW напритмер?

Цитата(Алексей1153 @ 10.7.2011, 0:52) *
>>Почему я сплошь и рядом наблюдаю первый вариант?
покажи пример

Наверное я слишком часто читал книги по QT, вот там просто пистрит подобными примерами..

#include <QtGUI>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    QSplitter   spl(Qt::Vertical);
    QTextEdit*  ptxt1 = new QTextEdit;
    QTextEdit*  ptxt2 = new QTextEdit;
    spl.addWidget(ptxt1);
    spl.addWidget(ptxt2);
    
    ptxt1->setPlainText("Line1\n"
                        "Line2\n"
                        "Line3\n"
                        "Line4\n"
                        "Line5\n"
                        "Line6\n"
                        "Line7\n"
                        );
    ptxt2->setPlainText(ptxt1->toPlainText());
    spl.resize(200,200);
    spl.show();
    
    return a.exec();
}


Цитата
нет, т.к. во-втором случае, как только выйдешь из функции - объект умрёт, а в-первом случае - останется жить. И, если ты сохранишь указатель на объект в-первом случае, то сможешь к этому объекту обращаться в будущем.

Это я понимаю, но рассматривается случай(как любаят писать при доказателствах теорем: "в том и только в том случае"), когда обект создан в начале и удалён в конце функции. Хотя является плохим тоном переносить обязанность удаления обекта на клиента, стараюсь избегать этого..

Цитата
сейчас напрямую выделение динамических объектов в памяти используется не так часто.
когда объектов много - то проще юзать различные "умные" указатели, за которыми не нужно следить, или пулы переменных, в которых "выделение" и "освобождение" памяти происходит куда быстрее, чем множественными вызовами для каждого элемента.

Знаю про "умные указатели", но не использую их так как пока пишу только для десктопа.. просто голова кругом идёт когда начинаешь использовать эти умные казатели, а вот про пулы переменных почитаю.. что-то не слышал.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
haiflive
  опции профиля:
сообщение 10.7.2011, 16:06
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 37
Регистрация: 8.7.2010
Пользователь №: 1868

Спасибо сказали: 1 раз(а)




Репутация:   0  


Вот нагуглил такое правило, думаю его и буду придерживаться:
Цитата
для локальных данных функции лучше подходит стэк для всего остального куча.
Если объем данных превышает некое пороговое значение (начиная с 4КБ) или размер данных динамический то можно начинать думать о размешении их в куче.


Вот уж не думал, что затронул священную войну про то, где размещать переменные в стеке или в куче, оказалось и ссылочные типы и.. как их там.. "простые" могу рамещаться, как в стеке так и в куче, это решает операционная система и компилятор по каким-то "магическим" правилам..

Ну я для себя решил, сандартные типы в стек однозначно, пользователские типы.. тут надо думать в каждом случае отдельно, чаще думаю будет куча, в зависемости от размера объекта..

Всем спасибо за ответы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 10.7.2011, 16:20
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


haiflive, тут всё просто: Если объект должен жить за пределами функции в которой он создан - без new никуда.
И если объект сложный, обычно со скрытыми оператором присваивания и конструктором копирования - без new никуда.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 11.7.2011, 18:17
Сообщение #8


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(haiflive @ 10.7.2011, 9:57) *
Знаю про "умные указатели", но не использую их так как пока пишу только для десктопа.

это очень странное утверждение :)
"умные" указатели - всего лишь удобство для работы с динамическим распределением памяти. они помогают избегать утечек памяти, которые потенциально могут произойти, если программист где-то забыл удалить созданный ранее объект. а уж куда их применять - дело совершенно добровольное. они не намного медленнее, чем обычные указатели. я их в своём софте использую повсеместно, хотя у меня часто риал-тайм. разница во временах совершенно несущественная.
а вот если надо выделять кучу мелких объектов и с ними работать - тогда пулы удобнее. потом разом весь пул очищать можно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 16.4.2024, 7:04