другой тип создания экземпляров на C ++ - PullRequest
2 голосов
/ 05 января 2010

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

ClassA obj1; // this is going to stack

метод 2:

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

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

ClassA  obj2 = new obj2();

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

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 05 января 2010

Действительно, переход на 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/ - вы, вероятно, тоже найдете его, он предлагает много хороших объяснений

2 голосов
/ 05 января 2010

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

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

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

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

1 голос
/ 05 января 2010

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

ClassA obj1;

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

ClassA obj1(5);
...