2015-03-19 2 views
0

У меня есть этот унаследованный код: 2 вопросы, первый, почему они делают это указатель на указатель на ссылку вар:C++, что есть смысл получать указатель на указатель на адрес

cData& acData = *(*CacheVectorIter); //WHAT IS IT ? 

и делает это удалить реальный объект или просто указатель на объект?

delete &acData; 

это код (модифицированный)

for (CacheVector::iterator CacheVectorIter = m_Cache.begin(); 
      CacheVectorIter != m_Cache.end(); 
      ++CacheVectorIter) { 
      if (*CacheVectorIter != NULL) { 
      cData& acData = *(*CacheVectorIter); //WHAT IS IT ? 

      for (ObjectTypeMap::iterator ObjectTypeMapIter = acData.Map.begin(); 
        ObjectTypeMapIter != acData.Map.end(); 
        ++ObjectTypeMapIter) { 

       delete (*ObjectTypeMapIter).second; 

      } 
       delete &acData; // DOES IT DELETE THE OBJECT OR THE POINTER? 
      } 
} 
+0

Кажется, что 'm_Cache' объявлен как контейнер, содержащий указатели, тогда первый оператор разыменования для итератора, второй - для разыменования фактического указателя, а' acData' является ссылкой на эти данные. Затем использование адреса-оператора на 'acData' даст вам указатель на объект, который он ссылается, который вы можете удалить. –

+0

Они просто создают ссылку на данные, на которые указывает итератор, поэтому они могут использовать точечный синтаксис и не использовать везде, где есть ведение указателя (* CacheVectorIter) -> Map.begin(); ' – Joe

+0

Почему ?, вы ссылаетесь область в куче, вы можете удалить ее. Синтаксис крайне уродлив, но действителен. – Raistmaj

ответ

0
cData& acData = *(*CacheVectorIter); //WHAT IS IT ? 

m_cache является контейнером хранения указателей, так что предыдущая строка будет получить указатель и derefence его, чтобы назначить его к ссылке.

cData& acData = data; 

Эта линия будет полностью действительным, но это не

cData& acData = &data; 

Теперь, может быть, самая шокирующая часть

delete &acData; // DOES IT DELETE THE OBJECT OR THE POINTER? 

Даже если я не согласен с этим видом синтаксиса, является как эта ссылка относится к объекту в куче, и вы можете удалить его.

Помните, что ссылки не называются деструктором!

+1

'Помните, что ссылки не называют деструктором! Что это значит? Хотя необычные 'delete & acData' вызовут деструктор. –

+0

Локальная ссылка не содержит данные, просто ссылку на нее. Обычный способ думать о ссылках - это способ абстрактного синтаксиса указателя. Поэтому, если вы используете ссылку в локальном коде, механизм по умолчанию для C++ C++ не будет использоваться. Удалить & acData; вызовет деструктор как разыменование ссылки возвращает указатель, если эта память хранится в куче, тогда он сначала вызовет метод ~ Class(), а затем вызовет бесплатный (указатель); – Raistmaj

+0

Нет такой вещи, как «детекция ссылки». «Синтаксис абстрактного указателя» - это плохой способ думать о ссылках, ИМО. 'delete Anybody;' вызывает деструктор, потому что это то, что делает 'delete'. (за исключением типов без деструктора, конечно). –

0

Петля for предполагает, что cData является UDT; он имеет переменную члена Map, которая может быть std::map.

Таким образом, m_Cache является контейнером. Он содержит какой-то объект (мы не можем сказать из этого кода), но этот объект может быть применен для получения объекта типа cData. Содержащиеся объекты могут быть типа cData *, но в равной степени это может быть некоторый умный указатель или другой класс.

Так линия:

cData& acData = *(*CacheVectorIter); 

acData связывается как имя для объекта, который обеспечиваемое применением * к объекту в контейнере. (Он не копирует объект из контейнера или ничего). Обратите внимание: круглые скобки являются излишними.

Линия:

delete &acData; 

освободит cData объект. Если элементы m_Cache являются на самом деле указателями, то это то же самое, что и вызов delete на одном из этих указателей.

Этот код является сомнительным, поскольку он оставит контейнер, содержащий оборванный указатель (который рискует вызвать неопределенное поведение); надеюсь, что это часть более крупного блока кода, который также очищает весь вектор.

Было бы интересно, если бы вы могли опубликовать определение класса того, что m_Cache является объектом; а также определение класса cData. Это позволило бы дать более точный ответ.

+0

Спасибо, но все-таки почему бы не просто получить Iterator в cData * pacData, зачем использовать ссылку varibal? – user63898

+1

@ user63898 ссылки более безопасны и просты в использовании. Однако использование указателя будет иметь тот же эффект, что и внутренне, ссылки реализуются как указатели. –

0

Хорошо, так давайте сначала рассмотрим *CacheVectorIter

Тип *CacheVectorIter является CacheVector и это способ получить текущий элемент (ничего нового).

Теперь у вас есть *(CacheVector), который является странным. В принципе без объекта CacheVector я не смогу сделать больше, чем просто угадать.

Я предполагаю, что CacheVector содержит адрес другого объекта. Используя *(CacheVector), вы можете получить доступ к этому другому объекту (вероятно, типа cData).

Это дает:

*(*CacheVectorIter) = *(CurrentCacheVector) = cData 

Затем этот объект сохраняется в переменной-ссылки acData. В C++ вы можете представить ссылку как указатель, который вам не нужен для разыменования. Таким образом, удаление acData действительно вызовет деструктор объекта.

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