LINUX.ORG.RU

[qt] что почитать о потоках? [c++] new

 ,


0

0

Не знаю ничего про потоки, что-нибудь есть на русском, где вкратце написано о всех возможностях распараллеливания в Qt? Нужно чтобы определиться, что конкретно мне нужно, и потом уже смотреть в qt-docs.

И ещё дуракий вопрос. Почти уверен, что всё верно, но мало ли...

class MyClass {
  MyOtherClass *m_object1;
  MyOtherClass *m_object2;
public:
  MyClass():
    m_object1(new MyOtherClass),
    m_object2(new MyOtherClass)
  {  }

  ~MyClass() {
    delete m_object1;
    delete m_object2;
  }

  void someFunction1()
  {
    delete m_object1;
    m_object1 = NULL
  }

  void someFunction2()
  {
    delete m_object1;
    m_object1 = new MyOtherClass;
  }
};

Всё ли ок с кодом, или лучше сделать как-то иначе (речь о расово верном использовании new)?

★★★★★

Последнее исправление: Obey-Kun (всего исправлений: 1)

Программирование в потоках обычно малоэффективно. В qt есть consurence (ну или как-то так называется) - неплохой framework для распоралеливания (хотя я до сих пор не разу распараллеливание не использовал в работе)

А про память. Еще раз - не храните по указателю. Для этого есть умные указатели. Хоть auto_ptr и имеет пару неприятных подводных камней, но с ними можно жить. А вот с этим нельзя.

m_object1 = NULL

Нет NULL в С++. Надо использовать 0 (представь, что твой код будет собираться там, где невалидный адрес отличен от 0) - это явное указание компилятору на невалидный адрес (ибо бывает, что NULL = (void*)-1 )

Вообще после удаления указателю лучше занулять - тогда проще ловить ошибки обращения к ним после delete

namezys ★★★★
()
Ответ на: комментарий от lester

> утечка памяти

тьфу, у себя я разумеется удаляю старое предварительно, то есть на самом деле так

[code=cpp] void someFunction2() { delete m_object2; m_object1 = new MyOtherClass; } [/code]

В топике косяк, да.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от lester

> ерунда

В стандарте четко об этом сказано. Ибо когда пишешь на С, ты сравниваешь указатель с нулем. А когда пишешь на С++ - его надо приводить к bool.

Да, и еще одна причина - размер указателя не всегда sizeof(void*)

namezys ★★★★
()
Ответ на: комментарий от namezys

> В стандарте четко об этом сказано

http://ru.wikipedia.org/wiki/NULL_%28%D0%A1%D0%B8%29#.D0.9D.D1.83.D0.BB.D0.B5...

Да, и еще одна причина - размер указателя не всегда sizeof(void*)


если не брать во внимание указатели на методы, то когда такая ситуация еще бывает?

lester ★★★★
()
Ответ на: комментарий от lester

Вот там как раз про С++ написано

Ну начнем с того, что проверка на возможность удаления объекта: это static_cast<bool>(p). Второе, если NULL будет равен -1 --- то у нас вообще компиляция не пройдет.

В общем это конечно дело привычки, но...

namezys ★★★★
()

Кстати, хотелось бы всем сказать спасибо за помощь с c++ и qt4.

Программу дописал но работающего состояния, так что вчера впервые смог запустить рассчёт созданной юзером в гуе модели.

http://rghost.ru/1337283/image.png

Успел вовремя: первая модель была успешно запущена через час после начала конференции, на которой я её должен был показывать, так что повезло, что я с коллегой был в конце списка защищающихся.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от namezys

> Второе, если NULL будет равен -1 --- то у нас вообще компиляция не пройдет

в стандарте написано, что NULL == 0, а переопределить можно и for, и return и все что угодно - и тоже компиляция не пройдет

lester ★★★★
()

насчёт кода ясно, а про qt threads посоветуете что почитать? :)

пора уже рассчёты отделить от гуя, чтоб можно было визуализацию в реальном времени делать.

Obey-Kun ★★★★★
() автор топика

>delete m_object1;
m_object1 = new MyOtherClass;


У меня сейчас будет еще более дурацкий вопрос. Вот здесь удаляется объект, следовательно освобождается память. Далее выделяется память для такого же объекта. Какова вероятность что под него выделится та же память?

Turbid ★★★★★
()
Ответ на: комментарий от Turbid

>та же память?
та же область памяти.

похоже сам уже понял - пока указатель не обнулишь - так и будет, так?

Turbid ★★★★★
()
Ответ на: комментарий от lester

В стандарте С написано что NULL - невалидный указатель. Он может быть на некоторых платформах и -1, и 0xFFFF.

Соответственно NULL в С++ будет такой же, как и в С

namezys ★★★★
()
Ответ на: комментарий от Turbid

> Далее выделяется память для такого же объекта. Какова вероятность что под него выделится та же память?

Достаточно вероятно, но только потому что так написано malloc/free под linux

В общем случае нет - если надо добиться этого, пишеться специфичный аллокатор

namezys ★★★★
()
Ответ на: комментарий от namezys

> В стандарте С написано что NULL - невалидный указатель

Соответственно NULL в С++ будет такой же, как и в С


NULL определяется в <cstring> и равен 0, это стандарт С++, что непонятного?

lester ★★★★
()
Ответ на: комментарий от namezys

> В общем случае нет - если надо добиться этого, пишеться специфичный аллокатор

который называется new

lester ★★★★
()
Ответ на: комментарий от lester

> NULL определяется в <cstring> и равен 0, это стандарт С++, что непонятного?

Хм. Это точно прописано в стандарте? Просто не знал - я слышал другое мнение, которому я доверяю.

Судя по wiki, в ANSI С (bool)p == 0, а в С++ static_cast<bool>(p) == false

namezys ★★★★
()
Ответ на: комментарий от namezys

Вспомнил, когда в С++ для указателей физически лежит не 0 для валидного адреса: указатель на члены структуры

namezys ★★★★
()
Ответ на: комментарий от vaulter

блин. надо включать мозг и думать, что пишу

(int)p == 0 конечно же

namezys ★★★★
()
Ответ на: комментарий от antony986

Бланшет не радует, а Шлее дома валятся... как-то даже забыл о его существовании после забота к конференции, надо будет почитать :). Спасибо.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

да, щаз скачал, у Шлее поболя будет, все таки первая книга это совсем для начинающих

antony986
()
Ответ на: комментарий от Turbid

похоже сам уже понял - пока указатель не обнулишь - так и будет, так?

Хм, разве так? Сомневаюсь. Иначе очень странно получается:

MyObject *a;
a = new MyObject;
MyObject *b;
b = a;
a = new MyObject; // по твоей логике теперь b ссылается на новый объект, а не на старый

Аналогично

MyObject *a;
a = new MyObject;
MyObject *b;
b = a;
b = new MyObject; // по твоей логике теперь a ссылается на новый объект, а не на старый

А вообще, следует читать всё так:

ptr = new MyObject;

Сначала выполняется new, а потом «=». То есть сначала забирается память из кучи, где создается объект. После этого ptr становится указателем на только что созданный объект. Если он до этого ссылался на какую-то другую область памяти, то это никак не должно повлиять на неё. Он просто теперь указывает на другую область. И если больше ничто не указывает на ту область, куда он указывал до этого, то у нас получается не к чему выделенная память, по сути утечка памяти.

Obey-Kun ★★★★★
() автор топика

добавь конструктор копий и переопредели оператор присваивания, ато после присваивании у тебя поля(m_object1 и m_object2) как источника так и приемника будут равны и в деструкторе память будет освобождатся дважды или после удаления одного из обьектов другой будет ссылатся на освобожденный участок памяти. Или запрети их обоих (В Qt: private: Q_DISABLE_COPY(MyClass)).

Devix
()
Ответ на: комментарий от Devix

ого, не задумывался, спасибо за подсказку!

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от lester

>в стандарте написано, что NULL == 0, а переопределить можно и for, и return и все что угодно - и тоже компиляция не пройдет

да-дад. #define true false // счастливой отладки!

slackwarrior ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.