Название: параметр конструктора Отправлено: blood_shadow от Январь 08, 2011, 21:41 Всем добрый вечер,
Почему работает данный код: Код: class Cell : QTableWidgetItem а именно почему мы можем передать конструктору параметр *this в передпоследней строке если у него нет параметров? Название: Re: параметр конструктора Отправлено: alexman от Январь 08, 2011, 21:43 Так конструктор копирования всегда есть по умолчанию.
Название: Re: параметр конструктора Отправлено: Fat-Zer от Январь 08, 2011, 21:48 Если хотите запретить надо сделать его закрытым...
Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 08, 2011, 22:05 Так конструктор копирования всегда есть по умолчанию. а понял, все время забываю о конструкторе копирования :)этот фрагмент я выдрал с книги Саммерфильда и Бланшета, тогда еще такой вопрос зачем копировать если можно допустим просто создавать объект или эт будет быстрее? Название: Re: параметр конструктора Отправлено: alexman от Январь 08, 2011, 22:09 Вопрос непонятен. Лучше почитай где используется конструктор копирования.
Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 08, 2011, 23:11 Вопрос непонятен. Лучше почитай где используется конструктор копирования. все разобрался...остался вопрос по поводу записи: Код: return new Cell(*this); Я правильно мыслю? Название: Re: параметр конструктора Отправлено: Fat-Zer от Январь 08, 2011, 23:17 да... только не "побитовою"
Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 08, 2011, 23:27 да... только не "побитовою" а какой? вроде же конструктор копирование делает побитовую копию, это я прочитал в книге Шилдта, там написано:"По умолчанию, если один объект инициализируется другим, создается побитовая копия присваиваемого объекта" значит если это верно то и в куче должна появиться побитовая копия объекта Название: Re: параметр конструктора Отправлено: alexman от Январь 09, 2011, 00:23 да... только не "побитовою" а какой? вроде же конструктор копирование делает побитовую копию, это я прочитал в книге Шилдта, там написано:"По умолчанию, если один объект инициализируется другим, создается побитовая копия присваиваемого объекта" значит если это верно то и в куче должна появиться побитовая копия объекта Название: Re: параметр конструктора Отправлено: Fat-Zer от Январь 09, 2011, 00:25 имел в виду, что реально не копируется каждый бит по отдельности... в лучшем случае побайтовую, а скорей всего всё будет делаться одной/двумя инструкциями. просто правильнее было бы сказать точную копию. не перите в голову. просто не понравилось слово ;)
да, brankovic прав. моя ошибка. Название: Re: параметр конструктора Отправлено: brankovic от Январь 09, 2011, 01:33 "По умолчанию, если один объект инициализируется другим, создается побитовая копия присваиваемого объекта" Это полная ерунда. На самом деле: struct X { int i; char ch; std::string s; }; конструктор копирования X вызовет конструктор копирования для каждого элемента. Для i и ch это, конечно, побитовая копия, но для s это вызов конструктора std::string, с маллоками, копированием байт и т.д. Название: Re: параметр конструктора Отправлено: juvf от Январь 09, 2011, 08:38 "Философия С++. Введение в стандарт", Брюс Эккель, глава 11, стр. 344
Цитировать Чтобы создать копирующий конструктор для класса, использующего композицию (а также наследование - глава 14), компилятор рекурсивно вызывает копирующие конструкторы всех объектов класса и базовых классов. Там же, в этой главе, примеры, доказывающие это. В вашем случае blood_shadow , с классом Cell, вывозится коп. конст. для QTableWidgetItem. Смотрим асистентЦитировать QTableWidgetItem::QTableWidgetItem ( const QTableWidgetItem & other ) Попробуйте проверить. Создайте класс Cell, задайте type и tableWidget. создайте копию и посмотрите у копии type и tableWidget. Если у Cell был поразрядный конструктор, то type и tableWidget должны сохранится.Constructs a copy of other. Note that type() and tableWidget() are not copied. Название: Re: параметр конструктора Отправлено: Igors от Январь 09, 2011, 09:11 имел в виду, что реально не копируется каждый бит по отдельности... в лучшем случае побайтовую, а скорей всего всё будет делаться одной/двумя инструкциями. просто правильнее было бы сказать точную копию. не перите в голову. просто не понравилось слово ;) Никакого "копирования памяти" не происходит. Default конструктор копирования вызывает конструкторы копирования для всех членов. В ассемблере это обычно большой кусок кода. "Точная копия" гарантируется только для POD структур. Кароче читайте книжки и учите С++ ;) :)Edit: пардон, просмотрел: brankovic уже ответил Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 09, 2011, 12:35 Цитировать Попробуйте проверить. Создайте класс Cell, задайте type и tableWidget. создайте копию и посмотрите у копии type и tableWidget. Если у Cell был поразрядный конструктор, то type и tableWidget должны сохранится. думаю автор книги имел ввиду правило про данные, хотя как оказалось с постов выше это и для данных-объектов неверно Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 09, 2011, 12:56 конструктор копирования X вызовет конструктор копирования для каждого элемента. Для i и ch это, конечно, побитовая копия, но для s это вызов конструктора std::string, с маллоками, копированием байт и т.д. в этой записи: Код: return new Cell(*this); тут сразу новый(скопированный объект конструктором копирования) появляется в куче? или еще раз копируются в кучу потом после создания копии? Название: Re: параметр конструктора Отправлено: Igors от Январь 09, 2011, 16:59 в этой записи: "Сразу" ничего появиться не может. Выделяется память в куче под объект и вызывается конструктор копирования которыйКод: return new Cell(*this); - сначала выполняет спец. действия для распределенного объекта (напр прописывает указатель на VMT) - вызывает конструкторы копирования для каждого члена объекта Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 09, 2011, 18:22 Цитировать "Сразу" ничего появиться не может. Выделяется память в куче под объект и вызывается конструктор копирования который а как насчет приоритета операций? то есть я имею ввиду что следуя приоритету операция сначала должен вызваться конструктор копирования Cell(*this) и только потом вызов оператора new или приоритет операции "()" не имеет отношения к созданию/копированию объекта? Название: Re: параметр конструктора Отправлено: Igors от Январь 09, 2011, 18:31 извиняюсь за дотошность - Не имеет. Сначала распределяется память, затем зовется конструктор (копирования или какой указали) а как насчет приоритета операций? то есть я имею ввиду что следуя приоритету операция сначала должен вызваться конструктор копирования Cell(*this) и только потом вызов оператора new или приоритет операции "()" не имеет отношения к созданию/копированию объекта? Название: Re: параметр конструктора Отправлено: lit-uriy от Январь 09, 2011, 18:44 >>и только потом вызов оператора new или приоритет операции "()"
здесь нет операции скобки, это форма записи любой функции: funcname() , а в данном случае конструктора Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 09, 2011, 18:59 здесь нет операции скобки, это форма записи любой функции: вроде ж как конструктор - это не ф-ция и я так предполагаю что конструктор копирования тоже нет.funcname() , а в данном случае конструктора а если посмотреть по приоритету операторов то вот этот оператор вызова ф-ции "()" стоит почти в самом верху выше new, осмелюсь предположить что если new вызывается первым то и конструктор не является ф-цией и создание/копирование объекта носит немного другой характер нежели просто оператор вызова ф-ции Если неправ, поправьте пожалуйста Название: Re: параметр конструктора Отправлено: Igors от Январь 09, 2011, 20:50 осмелюсь предположить что если new вызывается первым то и конструктор не является ф-цией и создание/копирование объекта Конечно прав, ф-цию в new никак не воткнуть. А лучше/проще в отладчике посмотреть чем листать книги :) По ходу дела: с new можно и не выделять память в куче, а указать адрес. Это ценная возможностьносит немного другой характер нежели просто оператор вызова ф-ции Если неправ, поправьте пожалуйста Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 09, 2011, 23:09 Конечно прав, ф-цию в new никак не воткнуть. А лучше/проще в отладчике посмотреть чем листать книги :) По ходу дела: с new можно и не выделять память в куче, а указать адрес. Это ценная возможность извиняюсь за скудость своих познаний, но буду очень вам благодарен если скажете как в отладчике посмотреть что первое вызывается, использую креатор с gdb отладчиком, поставил точку останова на строке Код: return new Cell(*this); Спасибо :) Название: Re: параметр конструктора Отправлено: brankovic от Январь 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); //аргументы могут быть любые, главное чтобы существовал такой конструктор Он (упрощенно) эквивалентен вызову функции: Код
обратите внимание на конструкцию: new (ptr) Cell (c); это и есть placement new. По смыслу это ptr->Cell::Cell (c); , т.е. вызов конструктора копирования с this равным ptr, но просто вызвать конструктор как я написал нельзя -- компилятор ругнётся. Зачем так сделано я не знаю, но так обстоят дела. Этот placement new используется для написания контейнеров, но в обычной жизни можно без него обойтись. P.S.: конструктор это именно функция, такая же как и остальные, просто с некоторыми отклонениями в части синтаксиса. А в записи "new Class (a, b, c)" никакого вызова функции нет, это вызов оператора new. Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 10, 2011, 01:18 Создайте явно конструктор копирования Cell (Cell const &) и в нём поставьте брейк. Увидите по стеку, что вы внутри оператора new. Но вы всё равно кода new не увидите, его генерит gcc сразу в ассемблер. Не знаю что даже сказать, конструктор копирования создан, точка поставлена, вот что получилось: (http://img209.imageshack.us/img209/56/debug.jpg) как-то оно бедно и помоему ничего не очевидно Название: Re: параметр конструктора Отправлено: blood_shadow от Январь 10, 2011, 01:39 Код
Код: return new Cell (*this); Название: Re: параметр конструктора Отправлено: juvf от Январь 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. Последовательность сообщений в кансоле и будет последовательностью вызова функций.Название: Re: параметр конструктора Отправлено: brankovic от Январь 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. |