Russian Qt Forum
Ноябрь 24, 2024, 03:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: параметр конструктора  (Прочитано 11122 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #15 : Январь 09, 2011, 16:59 »

в этой записи:
Код:
return new Cell(*this);
тут сразу новый(скопированный объект конструктором копирования) появляется в куче? или еще раз копируются в кучу потом после создания копии?
"Сразу" ничего появиться не может. Выделяется память в куче под объект и вызывается конструктор копирования который
   - сначала выполняет спец. действия для распределенного объекта (напр прописывает указатель на VMT)
   - вызывает конструкторы копирования для каждого члена объекта
Записан
blood_shadow
Гость
« Ответ #16 : Январь 09, 2011, 18:22 »

Цитировать
"Сразу" ничего появиться не может. Выделяется память в куче под объект и вызывается конструктор копирования который
извиняюсь за дотошность -
а как насчет приоритета операций? то есть я имею ввиду что следуя приоритету операция сначала должен вызваться конструктор копирования Cell(*this)
и только потом вызов оператора new или приоритет операции "()" не имеет отношения к созданию/копированию объекта?   
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Январь 09, 2011, 18:31 »

извиняюсь за дотошность -
а как насчет приоритета операций? то есть я имею ввиду что следуя приоритету операция сначала должен вызваться конструктор копирования Cell(*this)
и только потом вызов оператора new или приоритет операции "()" не имеет отношения к созданию/копированию объекта?   
Не имеет. Сначала распределяется память, затем зовется конструктор (копирования или какой указали)
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #18 : Январь 09, 2011, 18:44 »

>>и только потом вызов оператора new или приоритет операции "()"
здесь нет операции скобки, это форма записи любой функции:
funcname()
, а в данном случае конструктора
Записан

Юра.
blood_shadow
Гость
« Ответ #19 : Январь 09, 2011, 18:59 »

здесь нет операции скобки, это форма записи любой функции:
funcname()
, а в данном случае конструктора
вроде ж как конструктор - это не ф-ция и я так предполагаю что конструктор копирования тоже нет.
а если посмотреть по приоритету операторов то вот этот оператор вызова ф-ции "()" стоит почти в самом верху выше new,
осмелюсь предположить что если new вызывается первым то и конструктор не является ф-цией и создание/копирование объекта
носит немного другой характер нежели просто оператор вызова ф-ции
Если неправ, поправьте пожалуйста
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Январь 09, 2011, 20:50 »

осмелюсь предположить что если new вызывается первым то и конструктор не является ф-цией и создание/копирование объекта
носит немного другой характер нежели просто оператор вызова ф-ции
Если неправ, поправьте пожалуйста
Конечно прав, ф-цию в new никак не воткнуть. А лучше/проще в отладчике посмотреть чем листать книги  Улыбающийся По ходу дела: с new можно и не выделять память в куче, а указать адрес. Это ценная возможность
Записан
blood_shadow
Гость
« Ответ #21 : Январь 09, 2011, 23:09 »

Конечно прав, ф-цию в new никак не воткнуть. А лучше/проще в отладчике посмотреть чем листать книги  Улыбающийся По ходу дела: с new можно и не выделять память в куче, а указать адрес. Это ценная возможность
извиняюсь за скудость своих познаний, но буду очень вам благодарен если скажете как в отладчике посмотреть что первое вызывается, использую креатор с gdb отладчиком, поставил точку останова на строке
Код:
 return new Cell(*this); 
но он выдает только адреса ф-ций Cell::clone() и main и также указатель this на что ссылается и больше ничего, если пошагово потом исполнять дает только адрес указателя которому присваивается возврат указателя
Спасибо  Улыбающийся
Записан
brankovic
Гость
« Ответ #22 : Январь 10, 2011, 00:39 »

поставил точку останова на строке
Код:
 return new Cell(*this); 

Создайте явно конструктор копирования Cell (Cell const &) и в нём поставьте брейк. Увидите по стеку, что вы внутри оператора new. Но вы всё равно кода new не увидите, его генерит gcc сразу в ассемблер.

Не заморачивайтесь про приоритет операций, это одна операция "new Cell (*this)", просто синтаксис new в C++ весьма морочный. Новички с других языков часто отождествляют new и конструктор объекта -- это совершенно разные вещи! Для пущей путаницы операторов new несколько:
1. обычный new
2. placement new
3. ещё целый зоопарк, но нам они не важны

Вы используете обычный new:

return new Cell (*this); //аргументы могут быть любые, главное чтобы существовал такой конструктор

Он (упрощенно) эквивалентен вызову функции:

Код
C++ (Qt)
Cell *operator_new (Cell const &c)
{
  Cell *ptr = (Cell*) malloc (sizeof (Cell));
  if (ptr == 0)
     throw std::bad_alloc ();
  new (ptr) Cell (c); //***PLACEMENT NEW***
  return ptr;
}
 

обратите внимание на конструкцию:

new (ptr) Cell (c);

это и есть placement new. По смыслу это

ptr->Cell::Cell (c);

, т.е. вызов конструктора копирования с this равным ptr, но просто вызвать конструктор как я написал нельзя -- компилятор ругнётся. Зачем так сделано я не знаю, но так обстоят дела. Этот placement new используется для написания контейнеров, но в обычной жизни можно без него обойтись.

P.S.: конструктор это именно функция, такая же как и остальные, просто с некоторыми отклонениями в части синтаксиса. А в записи "new Class (a, b, c)" никакого вызова функции нет, это вызов оператора new.
« Последнее редактирование: Январь 10, 2011, 01:20 от brankovic » Записан
blood_shadow
Гость
« Ответ #23 : Январь 10, 2011, 01:18 »


Создайте явно конструктор копирования Cell (Cell const &) и в нём поставьте брейк. Увидите по стеку, что вы внутри оператора new. Но вы всё равно кода new не увидите, его генерит gcc сразу в ассемблер.


Не знаю что даже сказать, конструктор копирования создан, точка поставлена, вот что получилось:

как-то оно бедно и помоему ничего не очевидно
Записан
blood_shadow
Гость
« Ответ #24 : Январь 10, 2011, 01:39 »



Код
C++ (Qt)
Cell *operator_new (Cell const &c)
{
  Cell *ptr = (Cell*) malloc (sizeof (Cell));
  if (ptr == 0)
     throw std::bad_alloc ();
  new (ptr) Cell (c); //***PLACEMENT NEW***
  return ptr;
}
 

в этом коде с объявлением оператора так как выше
Код:
 return new Cell (*this); 
вызов new будет выглядеть вот так: operator_new(Cell (*this)) или он будет вызываться как-то по другому не так как ф-ция?
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #25 : Январь 10, 2011, 06:34 »

to blood_shadow
Цитировать
это не из-за того, тут и так понятно что ф-ции не копируются более того ф-ции существуют еще до создания любых объектов
да я вроде про функции не говорил. Может смутила запись из асистанта "Note that type() and tableWidget() are not copied." Ну я её понимаю не буквально, я понимаю что параметр type (его тип int), который получил конструктор, не скопируется. Также table widget that contains the item (тип QTableWidget *) не скопируется.

Цитировать
но буду очень вам благодарен если скажете как в отладчике посмотреть что первое вызывается
ну так глобально переопределить оператор new и переопределить копирующий конструктор Cell. До кучи переопределить копирующий конструктор QTableWidgetItem. Чтоб с gdb не заморачиваться, можно в переопределённых конструкторах и в переопределённом new выводить что-нибудь в cout. Последовательность сообщений в кансоле и будет последовательностью вызова функций.
Записан
brankovic
Гость
« Ответ #26 : Январь 10, 2011, 13:17 »

вызов new будет выглядеть вот так: operator_new(Cell (*this)) или он будет вызываться как-то по другому не так как ф-ция?

operator_new (*this);

Но есть нюанс. Форма operator_new (Cell (*this)) тоже отработает, потому что распадается на 2 операции:

Cell tmp (*this);
operator_new (tmp);

Так же отработает operator_new (Cell (Cell (Cell (*this)))), такой вызов аналогичен:

Cell const a1 (*this);
Cell const a2 (a1);
Cell const a3 (a2);
operator_new (a3);

Только последний из объектов будет создан в куче, a1, a2 и a3 будут созданы на стеке безо всякого new.
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.101 секунд. Запросов: 22.