Доброе утро. У меня возникают проблемы с пониманием логики глубокого и поверхностного копирования с объектами на 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) Это глубокая или мелкая копия?
Я прошу прощения, если я пропустил важные биты. Я не очень программист, поэтому такие вещи легко смущают меня. Литература только смутила меня еще больше. Спасибо за ваше время.
«Почему элемент данных доступен как 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();
Я бы порекомендовал сначала закончить любую хорошую книгу по С ++, это решит кучу потенциальных вопросов, таких как этот