Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Как распределяет память конструктор копирования |
Автор: AlanG 12.6.2006, 12:20 | ||
Всем доброго времени суток ![]() Меня интересует как происходит распределения памяти при создании копии объекта. Имеем класс который содержит конструктор копирования. Как извесно, он распределяет НОВУЮ память для созданного объекта. Вот только не понятно ГДЕ и КАК он это делае? И еще, если в классе имеем оператор new который тоже распрелеляет память, какая тогда будет связь между памятью от конструктора непосредственно и памятью от оператора new ? Пример:
|
Автор: Earnest 12.6.2006, 12:30 |
Не "как известно", а "как напишешь". Конструкторы не распределяют память. Они инициализируют объект в той памяти, которую им дали. В твоем примере оба объекта создаются на стеке. Если ты в своей реализации конструктора выделяешь память оператором new, то это частный случай. Память выделяется всегда в куче (если ты используешь стандартный new). Никакой связи с тем, какую память получил конструктор, нет. Т.е. как бы ни был создан объект array (как глобальная переменная, как автоматический объект или динамически, через new) - внутренний new будет выделять память одинаково. |
Автор: AlanG 12.6.2006, 12:41 | ||
Я наверное НЕдописал кое что ![]() Конструкторы копирования, как раз таки распределяют память, для этого они и предусмотрены. Если конструктор копирования ЯВНО не реализован в програме, используется конструктор по умоляанию, но с ним пробдлема, при вызове деструктора, удаляется память каждого из созданных объектов (естественно из этого же класса). Когда создается новый объект (точнее копия объекта а), в данном случае он создается при создании нового объекта a2_copia. (еще может создаватся при вызове функций с передачей объекта). Копия создается именно в тот момент, когда передается параметр в виде объекта. Собствено вопрос: ГДЕ и КАК распределяется память для ЭТОЙ копии (копии объекта а)? Добавлено @ 12:42 Про new я зря упомянул, только запутал..... |
Автор: MAKCim 12.6.2006, 12:52 |
когда компилятор встречает вызов конструктора копирования для объекта, который будет размещен в стеке то скорее всего просто уменьшается указатель стека на sizeof(<структура, представляющая данные объекта класса>) ,байт и call-ом вызывается процедура, соответствующая конструктору копирования (или сгенерированному КК) и туда передается указатель на первый байт данных объекта (текущий (измененный) указатель стека). Собственно эта процедура и инициализирует поля объекта (то есть не занимается выделением памяти а работает уже с существующими адресами) |
Автор: AlanG 12.6.2006, 13:04 | ||||
Тогда я наверное чего то недопонял... Хорошо, а что происходит когда я передаю объект в качестве параметра, другой функции?
|
Автор: Earnest 12.6.2006, 13:05 | ||
Это тоже не так. Распределение\освобождение памяти и конструирование\разрушение объекта - это два разных процесса, никак не связанных. Т.е. только на вид они связаны. Выделение\освобождение памяти - это new\delete. При вызове деструктора память не удаляется. Когда ты пишешь MyClass* pa = new MyClass(аргументы); то сначала выделяется память (оператором new), а потом эта память передается конструктору для инициализации. Если объект размещается на стеке, то память не выделяется, а просто, как написал MAKCim, текущий указатель стека смещается на размер объекта, а предыдущий передается конструктору для инициализации (что-то типа placement new). Собственно, сам механизм placement new - это способ вызвать конструктор в нужной области памяти. Инициализация - это, грубо говоря, присваивание начальных значений данным и, в случае полиморфных классов, присваивание нужного адреса таблице виртуальных ф-й (возможно не одной). Деструктор ... да, в общем, может ничего не делать. Разве что подменяет \ очищает адрес vtable... |
Автор: Daevaorn 12.6.2006, 13:11 |
В данном случае объект-параметр a1 будет создан на стеке, т.к. передается по значению. |
Автор: MAKCim 12.6.2006, 21:07 | ||
1. Изменение указателя стека на размер объекта 2. Передача нужного адреса через стек в процедуру которая соответствует конструктору копий 3. Инициализация полей в этой процедуре 4. Вызов нужной функции (при этом объект будет находится по текущему указаателю стека + 4 байта (на 32 разрядных платформах)) |