2010-01-05 3 views
2

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

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: Я читал эти темы:

Different methods for instantiating an object in C++

Stack, Static, and Heap in C++

What and where are the stack and heap?

+0

У C# нет двух способов создания экземпляров, поскольку среда выполнения управляет памятью для вас. –

+0

В методе 1 obj является ссылкой на объект ClassA. В методе 2 obj является указателем на объект ClassA. new в C++ возвращает указатель на выделенную память. Вы должны указать новый тип создаваемого объекта. Отчасти поэтому третий вариант не работает. obj2 не был определен как объект. В этот момент кода это просто текст, который будет использоваться в качестве идентификатора для ссылки на объект после его создания. – iheanyi

ответ

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

1

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

ClassA obj1; 

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

ClassA obj1(5); 
2

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

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

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

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

Смежные вопросы