Форум программистов, компьютерный форум CyberForum.ru

Зачем вызывается конструктор при объявлении указателя на класс - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.69
Alex Z
27 / 1 / 0
Регистрация: 29.06.2011
Сообщений: 136
21.11.2012, 18:18     Зачем вызывается конструктор при объявлении указателя на класс #1
Не знаю, правильно или нет назвал тему...

Вот такая ситуация понятна:
C++
1
2
int * pHeap = new int;
*pHeap = 7;
Здесь мы выделяем в динамической памяти место для хранения числа типа int. Результатом команды new будет адрес ячейки в динамической памяти. Этот адрес мы и присваиваем созданному указателю. Ну а потом по этому указателю уже можем доступаться до ячейки.

Не понятна ситуация, когда в динамической памяти размещается объект какого-то класса. Пишем по-сути так же:
C++
1
Cat *pCat = new Cat;
Цитирую учебник: "В данном случае в операторе new использован стандартный конструктор класса, т.е. конструктор, применяемый без параметров. Следует напомнить, что при создании объекта класса вызов конструктора происходит всегда, независимо от того, размещается объект в стеке или в области динамической памяти." И всё, больше никаких объяснений нет. Я что понять не могу: а зачем вообще в этом случае вызывается конструктор? Ведь конструктор вызывается при создании объекта, например:
C++
1
Cat Frisky;
Здесь создаётся объект Frisky типа (класса) Cat. Значит тут вызывается конструктор. Это понятно. А здесь то зачем конструктор?:
C++
1
Cat *pCat = new Cat;
Тут же вроде объект не создаётся. Я понимаю так: команда new Cat выделяет необходимое количество места в динамической памяти. Например, если класс Cat содержит 2 переменные типа unsigned short int (возраст и вес кота), то будет выделено 4 байта. А потом адрес присваивается указателю pCat. Непосредственно объект то вроде бы не создаётся. Я вначале думал, что может в книге опечатка, нет, по ходу я туплю...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.11.2012, 18:18     Зачем вызывается конструктор при объявлении указателя на класс
Посмотрите здесь:

C++ Наследование(Не вызывается конструктор)
Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... C++
this(Всегда ли вызывается конструктор при не явной передачи объекта в конструктор) C++
Почему конструктор вызывается повторно при преобразовании типов? C++
C++ Объявление указателя на структуру в объявлении структуры
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11801 / 6780 / 765
Регистрация: 27.09.2012
Сообщений: 16,833
Записей в блоге: 2
Завершенные тесты: 1
21.11.2012, 18:29     Зачем вызывается конструктор при объявлении указателя на класс #2
Цитата Сообщение от Alex Z Посмотреть сообщение
Непосредственно объект то вроде бы не создаётся.
Как не создается? Почитайте еще раз что такое классы и про оператор new.

Добавлено через 3 минуты
Для примера, сделайте конструктор с параметром и в new укажите параметры:
C++
1
Cat *pCat = new Cat(34);
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.11.2012, 18:35     Зачем вызывается конструктор при объявлении указателя на класс #3
Цитата Сообщение от Alex Z Посмотреть сообщение
Я понимаю так: команда new Cat выделяет необходимое количество места в динамической памяти.
и вызывает конструктор. Это и есть динамическое создание объекта. А сырую память выделяют: malloc, calloc и realloc.
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
23.11.2012, 13:10     Зачем вызывается конструктор при объявлении указателя на класс #4
Тут же вроде объект не создаётся.
Это не так. Объект создается, поэтому вызывается конструктор. Простое объявление указателя не создает объект, его создает new. До создания объекта попытки манипулировать объектом через указатель выдаст ошибку исполнения.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.11.2012, 16:56     Зачем вызывается конструктор при объявлении указателя на класс #5
Цитата Сообщение от Alex Z Посмотреть сообщение
Цитирую учебник: "В данном случае в операторе new использован стандартный конструктор класса, т.е. конструктор, применяемый без параметров. Следует напомнить, что при создании объекта класса вызов конструктора происходит всегда, независимо от того, размещается объект в стеке или в области динамической памяти." И всё, больше никаких объяснений нет. Я что понять не могу: а зачем вообще в этом случае вызывается конструктор? Ведь конструктор вызывается при создании объекта
Учебник пишет, что объект создаётся и вызывается конструктор по умолчанию для инициализации объекта. Просто, в данном случае, создаётся объект без имени, доступ к которому обеспечивает указатель.

Добавлено через 4 минуты
Цитата Сообщение от Alex Z Посмотреть сообщение
Я понимаю так: команда new Cat выделяет необходимое количество места в динамической памяти. Например, если класс Cat содержит 2 переменные типа unsigned short int (возраст и вес кота), то будет выделено 4 байта. А потом адрес присваивается указателю pCat. Непосредственно объект то вроде бы не создаётся.
Именно так и создаётся объект класса, или вы создание объекта как-то по другому представляете?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
24.11.2012, 19:09     Зачем вызывается конструктор при объявлении указателя на класс #6
Цитата Сообщение от Alex Z Посмотреть сообщение
Ведь конструктор вызывается при создании объекта,
Вот именно.

Добавлено через 12 минут
Alex Z, раздели декларацию указателя и вызов конструктора, между ними поставь другую операцию и протрассируй.
C++
1
2
3
4
int a;
Cat *pCat=NULL; // Здесь создаётся указатель.
a=200;
pCat=new Cat; // А вот здесь зоздаётся объект.
И запомни, если правый операнд new - класс, то память выделяется для объекта, это и есть его создание. Объекты только так и создаются, просто иногда это прописывется сразу в декларации статического, или автоматического объекта. Разумеется, при создании объекта, конструктор должен инициировать его начальным значением.
Alex Z
27 / 1 / 0
Регистрация: 29.06.2011
Сообщений: 136
24.11.2012, 20:50  [ТС]     Зачем вызывается конструктор при объявлении указателя на класс #7
Цитата Сообщение от taras atavin Посмотреть сообщение
раздели декларацию указателя и вызов конструктора, между ними поставь другую операцию и протрассируй.
C++
1
2
3
4
int a;
Cat *pCat=NULL; // Здесь создаётся указатель.
a=200;
pCat=new Cat; // А вот здесь зоздаётся объект.
Да, так понятнее, спасибо.

Только единственное, слово NULL во 2-ой строчке, это то же самое, что и число 0, или чем-то отличается? Вот так можно?:
C++
1
2
3
4
int a;
Cat *pCat=0;
a=200;
pCat=new Cat;
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.11.2012, 20:59     Зачем вызывается конструктор при объявлении указателя на класс #8
Цитата Сообщение от Alex Z Посмотреть сообщение
это то же самое, что и число 0, или чем-то отличается?
То же самое.
ntny
7 / 7 / 0
Регистрация: 17.06.2012
Сообщений: 168
24.11.2012, 21:28     Зачем вызывается конструктор при объявлении указателя на класс #9
Добавлено через 11 минут
хм туплю кстати
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.11.2012, 02:44     Зачем вызывается конструктор при объявлении указателя на класс #10
taras atavin, new вполне может выделять сырую память, если что.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
struct S
{
    S() { std::cout << "C-tor" << std::endl; }
    ~S() { std::cout << "D-tor" << std::endl; }
};
 
int main()
{
    void* memory = operator new(sizeof(S));
    S* p = new (memory) S();
    p->~S();
    operator delete(memory);
}
http://ideone.com/BTVQ4p

Про корректность очистки памяти не могу сказать, ибо юзать такое приходится редко.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.11.2012, 12:41     Зачем вызывается конструктор при объявлении указателя на класс #11
Цитата Сообщение от Alex Z Посмотреть сообщение
Вот так можно?:
Можно, но без гарантии: NULL - это указатель в никуда, определённый, как простое целое, 0 - это именно 0. Обычно они совпадают, но не всегда, а зависит это от архитектуры, а не от языка. Например, у сигнальных процессоров 0 - вполне валидный адрес, а NULL - наоборот очень большой номер байта. Так вот, если вдруг не 0, то для NULL заменяешь дефайн и всё, а с нолём придётся этот 0 отлавливать по всей проге. А ещё лучше современный null_ptr.

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
p->~S(); operator delete(memory);
delete сам вызывает деструктор.

Добавлено через 2 минуты
Цитата Сообщение от ForEveR Посмотреть сообщение
taras atavin, new вполне может выделять сырую память, если что.
Может. Если его по-кривому перегрузить, или указать правым операндом void. Но предназначен он не для этого.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.11.2012, 13:00     Зачем вызывается конструктор при объявлении указателя на класс #12
taras atavin, Почитай про operator delete. Он не вызывает деструктор.
Может. Если его по-кривому перегрузить, или указать правым операндом void. Но предназначен он не для этого.
Ой-ли? placement new, не слышал?
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
25.11.2012, 13:11     Зачем вызывается конструктор при объявлении указателя на класс #13
Цитата Сообщение от ForEveR Посмотреть сообщение
Ой-ли? placement new, не слышал?
если не ошибаюсь, placement new выполняет диаметрально противоположную задачу.

Добавлено через 1 минуту
Цитата Сообщение от taras atavin Посмотреть сообщение
new вполне может выделять сырую память,
а placement new наоборот. новой памяти не выделяет, но "делает существующую несырой".
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.11.2012, 13:16     Зачем вызывается конструктор при объявлении указателя на класс #14
Цитата Сообщение от ForEveR Посмотреть сообщение
taras atavin, Почитай про operator delete. Он не вызывает деструктор.
Так и запишем: трассировать не пробовал.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.11.2012, 13:18     Зачем вызывается конструктор при объявлении указателя на класс #15
Kuzia domovenok, Все верно, это меня перекосило. Впринципе я отвечал про перегрузку на тему void* вторым аргументом. Как раз перегрузка, где void* вторым аргументом есть placement-new.

C++
1
2
3
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
void* operator new (std::size_t size, void* ptr) throw();
Добавлено через 1 минуту
taras atavin, Не понял. Ты споришь с тем, что функция operator delete не вызывает деструктор объекта или с чем?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.11.2012, 15:25     Зачем вызывается конструктор при объявлении указателя на класс #16
Я в трассировке видел такой вызов.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2012, 16:49     Зачем вызывается конструктор при объявлении указателя на класс
Еще ссылки по теме:

C++ При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О
Почему конструктор вызывается при присвоении объекта другому объекту C++
Ошибка C4307 при объявлении в main() указателя шаблона-класса C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.11.2012, 16:49     Зачем вызывается конструктор при объявлении указателя на класс #17
taras atavin, delete действительно вызовет деструктор. То есть

C++
1
2
T* p = new T();
delete p;
будет вызван деструктор T. НО

C++
1
2
T* p =new T();
operator delete(p);
деструктор вызван не будет.
Yandex
Объявления
25.11.2012, 16:49     Зачем вызывается конструктор при объявлении указателя на класс
Ответ Создать тему
Опции темы

Текущее время: 13:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru