C++ глубокое копирование с объектами
Доброе утро. У меня возникают проблемы с пониманием логики глубокого и поверхностного копирования с объектами на C++ в общем проекте, поэтому я создал следующий пример.
int main() {
ObjectAType* objecta = ObjectAType::New();
ObjectBType* objectb = ObjectBType::New();
// some operation to populate data members of object a
objecta->Operation();
// assume I have accessors to return datamembers of object a
// I wish to make a deep copy of SOME of those data members into object b
objectb->AlignWithA(objecta);
objecta->Delete();
objectb->Delete();
return 0;
}
Теперь задана функция объекта класса b следующим образом:
public:
void ObjectBType::AlignWithA(ObjectAType* objecta) {
this->ObjectBDataMember = objecta->DataAccessor();
}
protected:
int ObjectBDataMember;
И средство доступа к данным просто что-то вроде этого в классе def,
public:
int ObjectAType::DataAccessor() {
return this->ObjectADataMember;
}
protected:
int ObjectADataMember;
У меня есть несколько вопросов.
1) Поскольку в объекте b элемент данных объявлен как
int ObjectBDataMember;
а не как
int *ObjectBDataMember;
почему к элементу данных обращаются как
this->ObjectBDataMember
а не как
this.ObjectBDataMember
?
2) Это глубокая или мелкая копия?
Я прошу прощения, если я пропустил важные биты. Я не очень программист, поэтому такие вещи легко смущают меня. Литература только смутила меня еще больше. Спасибо за ваше время.
5 ответов
"Почему элемент данных доступен как this->ObjectBDataMember
а не как this.ObjectBDataMember
?"
Это потому что this
указатель, а ->
Оператор следует за указателем, который идет перед ним, чтобы получить доступ к члену, который идет после него.
"Это глубокая или мелкая копия?"
Если вы имеете в виду копию целочисленной переменной, вы можете назвать ее мелкой копией, но нет необходимости квалифицировать ее как таковую, потому что int
это не структура данных.
Термин " глубокое копирование " относится к рекурсивному копированию всех объектов, связанных с копируемым объектом: если структура данных S
содержит переменные-члены, которые являются указателями, глубокое копирование экземпляра S
(сказать, s1
) в другой случай S
(сказать, s2
) означает рекурсивное копирование каждого объекта, указанного переменными s1
чтобы s2
будут связаны с копиями этих объектов, а не с теми же объектами, к которым s1
связан (это было бы в случае мелкого копирования).
Здесь у вас нет переменных-указателей, поэтому понятие "глубокая" и "мелкая" копия теряет смысл в этом контексте.
В C++
this
определяется как (немодифицируемый) указатель на текущий объект. По этой причине вы используетеthis->aMember
чтобы получить доступaMember
, Это не зависит от типа, которыйaMember
есть. (Примечание: использованиеthis->aMember
эквивалентно просто использованиюaMember
до тех пор, пока нет локальных переменных или параметров функции, использующих это имя).Так как
ObjectBDataMember
является int, копирование его не называется ни поверхностным, ни глубоким. Эти понятия используются только в контексте копирования указателей.
Например:
ObjectBType* b1 = new ObjectBType();
ObjectBType* b2 = b1; // shallow copy. b1 and b2 refer to the same object.
ObjectBType* b3 = new ObjectBType(*b1); /* deep copy. b1 and b3 refer to
different objects that happen to have the same value. */
Ты используешь
->
когда у вас есть указатель, и.
когда у вас есть ссылка. Доступ к элементу данных осуществляется какthis->ObjectBDataMember
так какthis
неизменяемый указатель на себя Поэтому вам нужно->
(смещение) оператор для доступа к егоObjectBDataMember
, Следует отметить, что вам не нужно использовать самоссылкуthis
указатель для доступа к собственным членам данных объекта. Это просто стиль, используемый для подчеркивания того, что код обращается к собственному элементу данных объекта. Полезно, когда вы обращаетесь к элементам данных другого объекта, и они имеют одинаковые элементы (поскольку объект одного типа).Эти объекты не имеют выделенных объектов, просто простые старые типы данных. Так что это мелкая копия. Мелкая копия объекта копирует его значения, но не выделяет никаких новых объектов. Он только копирует указатели на любые выделенные объекты. Глубокая копия создает копию всех членов типа значения, а также создает свои собственные выделенные объекты (обычно копируя значения в исходных копируемых подобъектах объектов).
this->ObjectBDataMember
не имеет ничего общего с глубокой или мелкой копией. this
это указатель, так что его члены всегда доступны через ->
, Ну, вы могли бы сделать (*this).ObjectBDataMember
,
Разница между
int ObjectBDataMember;
а также
int *ObjectBDataMember;
если вы хотите установить это значение, вы должны сделать:
this->ObjectBDataMember = 5;
против
*(this->ObjectBDataMember) = 5;
- так как
this
являетсяObjectBType*
(указатель), поэтому для доступа к его членам необходимо указать->
, КСТАТИ,this
является неявной переменной в функциях-членах, и вы можете ее опустить:ObjectBDataMember = objecta->DataAccessor();
- Тип ObjectADataMember - int, это базовый тип (не составной), так что это просто копия. Temp "глубокая копия" применима к составным типам.
Я бы порекомендовал сначала закончить любую хорошую книгу по C++, это решит кучу потенциальных вопросов, таких как этот