Динамические объекты в с ++

Я пришел на C++ из C#, и я не понимаю, что такое динамический объект. Итак, представьте, что у вас есть класс A, и для создания объекта типа A *a = new A() это Normal, но что такое объект a? Это то же самое, что массив или что? Мы можем написать как [0] или [1]? Но что происходит, если мы перегружаем оператор [] и хотим создать динамический объект, если у нас есть данные и мы хотим получить данные нормально?

3 ответа

Решение

Если ты пишешь A * a = new A() конструктор по умолчанию для класса A вызывается и динамически распределяет память для одного объекта класса A и адрес выделенной памяти назначается указателю a, Так a указывает на объект класса A а не массив. Тем не менее, если вы хотите массив A объекты динамически, то вам придется написать что-то вроде этого A * a = new A[10], Это выделит память из 10 объектов A, И ты можешь написать a[0], a[1], ... a[9] для доступа к объектам массива.

Теперь, что произойдет, если мы перегрузим [] оператор? Если мы перегружаем [] оператор, то это должно означать, что класс A имеет какой-то массив внутри, и написав a[1], где a является объектом класса A, мы хотим получить элемент, расположенный во втором индексе. (Говоря в целом, вы можете иметь в виду что-либо еще, используя оператор индекса, но вы должны попытаться придерживаться первоначального значения оператора индекса). Но мы не можем ссылаться [] оператор на указатели, как это будет означать разыменование указателя. Таким образом, чтобы вызвать оператор индексации на указателе объекта, мы должны явно вызвать оператор индекса. Как это:

A * a = new A;
cout << a->operator[](0) << endl;

Создает один объект класса Aи писать a->operator[](0), Он явно вызывает перегруженный оператор индекса. Что если мы создадим массив динамически?

A * a = new A[6];
cout << a[0][0] << endl;

Первый подстрочный оператор предназначен для получения первого объекта в массиве объектов. Второй подстрочный оператор вызывает перегруженный подстрочный оператор объекта. a[0]

РЕДАКТИРОВАТЬ: я был неправ в отношении вызова оператора индекса класса А. Спасибо jschultz410, который исправил меня.

Указатель - это то, на что он похож, это то, что указывает куда-то еще.

Возьми свой пример

A* a = new A;

Это объявляет переменную a в качестве указателя. Он указывает на экземпляр (объект) A учебный класс.

Несколько графически это можно увидеть как

+---+      +---------------+
| а | ---> | экземпляр A |
+---+      +---------------+

В C# (и Java) это в основном единственный способ создания экземпляров классов. Все переменные являются (немного упрощенными) указателями.

В C++ у вас есть и другие альтернативы:

A a;

В приведенном выше определении говорится, что переменная a является примером A учебный класс. Это не ссылка, это не указатели, это A объект.

Теперь еще одно различие между двумя приведенными выше определениями: в первом случае A создается во время выполнения. Память выделяется для экземпляра при запуске программы. Во втором случае пространство для экземпляра выделяется компилятором во время компиляции. Однако в обоих случаях конструктор вызывается во время выполнения.

"a" - указатель (адрес памяти) на память, в которой расположен объект "A". Да, он ведет себя как массив. Однако у вас есть только один элемент, поэтому "a[0]" будет эквивалентно "*a". Не пытайтесь использовать [1] в вашем случае. Он скомпилируется, но, скорее всего, сбой при запуске. Если вы перегрузите [], это ваша проблема сейчас:-). Хотя вы не можете перегружать [] указателями.

Кстати, в C# 'a' также будет указателем (ссылкой) на объект, а не на сам объект.

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

В 'c+' вы также можете создавать ссылки вместо указателей.

Другие вопросы по тегам