другой тип создания экземпляров на c ++

с тех пор, как я перешел с C # на C ++, в C ++ для меня все выглядит сумасшедшим. Мне просто интересно, может ли кто-нибудь объяснить мне, почему у нас есть такие экземпляры в С ++: метод 1:

ClassA obj1; // this is going to stack

способ 2:

ClassA *obj1 = new ClassA(); //this is going to heap

тогда как у нас нет обычного способа создания экземпляров на C # на С ++:

ClassA  obj2 = new obj2();

и еще один вопрос в методе 1. Я получаю экземпляр из ClassA, но без (), и это именно то место, где я запутался, почему мы должны так инсталлировать? у нашего ClassA есть конструктор, но без скобок ??? почему мы называем его конструктором?

p.s: Прочитал эти темы:

Различные методы создания экземпляра объекта в C ++

Стек, статика и куча в C ++

Что и где находятся стек и куча?


person Seyed Vahid Hashemi    schedule 05.01.2010    source источник
comment
В C # нет двух способов создания экземпляров, потому что среда выполнения управляет памятью за вас.   -  person Siyuan Ren    schedule 08.12.2013
comment
В методе 1 obj - это ссылка на объект ClassA. В методе 2 obj является указателем на объект ClassA. new в C ++ возвращает указатель на выделенную память. Вы должны сообщить новому, какой тип объекта нужно создать. Отчасти поэтому третий вариант не работает. obj2 не был определен как объект. На этом этапе кода это просто текст, который будет использоваться в качестве идентификатора для ссылки на однажды созданный объект.   -  person iheanyi    schedule 16.05.2014


Ответы (3)


Действительно, переход на C ++ с таких языков, как Java или C #, может быть пугающим, я тоже через это прошел.

Первое и главное отличие состоит в том, что в C ++ вы почти всегда управляете своей собственной памятью. Создавая объект в куче, вы несете ответственность за его удаление, чтобы не происходило утечки памяти - это, в свою очередь, означает, что вы можете удалить его, когда сочтете нужным. При создании объекта в стеке он автоматически удаляется, когда выходит за пределы области видимости - вы должны быть осторожны, чтобы не использовать его после того, как он выйдет за пределы области видимости.

Пример:

void do_queue(B& queue)
{
    Evt *e = new Evt;
    queue.queueEvent(e); 
} // all well, e can be popped and used (also must be deleted by someone else!)

против

void do_queue(B& queue)
{
    Evt e;
    queue.queueEvent(&e); 
} // e is out of scope here, popping it from the queue and using it will most likely cause a sigseg

При этом два метода также значительно отличаются в одном аспекте: первый создает объект. Второй создает указатель на объект. Хорошая вещь в наличии указателей заключается в том, что вы можете передавать их как параметры, при этом в стек копируется только минимальная память (копируется указатель, а не весь объект). Конечно, вы всегда можете получить адрес объекта, размещенного в стеке, используя "&", или передать его как ссылку, однако при использовании объектов, размещенных в стеке, вы должны быть особенно осторожны с их областью действия.

Я нашел этот веб-сайт отличным ресурсом, когда перешел с Java на C ++: http://www.parashift.com/c++-faq-lite/ - вы, вероятно, тоже его найдете, он предлагает много хороших объяснений

person laura    schedule 05.01.2010

В C ++ вы должны решить, где вы хотите разместить свой объект. Под местом я подразумеваю, в какой памяти, стеке или куче.

Создание экземпляра объекта - это двухэтапный процесс. Сначала вам нужна память, и вы либо берете ее в стек, либо выделяете из кучи. Во-вторых, вы инициализируете память нужными вам значениями, то есть создаете объект, вызывая его функцию-конструктор.

Эти два синтаксиса предназначены для этих двух возможных разных мест памяти: стека и кучи.

Что касается синтаксиса и явно отсутствующей круглой скобки для выделенного в стеке объекта, это необходимо для устранения неоднозначности между определением и построением объекта и объявлением функции. Действительно, ClassA obj(); объявляет функцию, не принимающую параметров и возвращающую объект ClassA.

person Didier Trosset    schedule 05.01.2010

Синтаксис C ++ такой же. Если вы хотите использовать конструктор по умолчанию, вы просто вызываете его так:

ClassA obj1;

Если бы у вас был конструктор с параметром, вы бы назвали его так:

ClassA obj1(5);
person fretje    schedule 05.01.2010