Динамические объекты в с ++
Я пришел на 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+' вы также можете создавать ссылки вместо указателей.