c ++ this, * this, & instance в operator = function меня сильно смутило

0

В c++ operator = function я много читаю:

ClassA & ClassA::operator=(const ClassA & instance){
    if(this == &instance){
        return *this;
    }
    ......
    ......
    ......
}

"this" - это указатель, указывающий на текущий экземпляр ClassA, а "* this" - текущий адрес экземпляра. Но почему (этот == и пример)? "& instance" - это другой адрес экземпляра ClassA, "this" - это только указатель. почему (этот == и пример)??? Меня так смутили, спасибо за любую помощь. А также, экземпляр - это то же самое с адресом экземпляра?

  • 0
    Вообразите a = a; , но еще лучше, используйте идиому copy-swap.
  • 1
    Вы ошибаетесь в *this - это не адрес, а сам объект.
Теги:

4 ответа

0
Лучший ответ

если у вас есть экземпляр класса A, скажем x

A x;

//Equal operation

x = x;

В этом случае вы просто хотите снова назначить один и тот же объект себе, поэтому вам не нужно делать все копии для атрибутов объекта, чтобы избежать этих нежелательных операций присваивания, всегда используется условие if на самое начало проверить, назначаете ли вы один и тот же объект себе, вам просто нужно проверить, одинаковы ли адреса.

   '(this == &instance)'

здесь this указывает на x сейчас (т.е. удерживая адрес экземпляра объекта x), и когда вы выполняете операцию присваивания (x=x), экземпляр - это объект x, а & instance - адрес объекта x, и this также удерживает адрес x, поэтому условие if имеет значение true и то, что вы хотите сделать, просто снова присваивает тот же адрес & x (нет необходимости в глубоком копировании атрибутов объекта)

1

Вы правы, "это" - указатель. А указатель - это адрес! Таким образом, указатель и адрес совпадают, и я буду использовать эти термины в том же значении ниже. Я думаю, вы немного смущены с & и *, поскольку они означают разные вещи, когда применяются к типу и переменной.

ClassA & refVar; //this way you declare a reference
ClassA* pVar;  //this way you declare a pointer
refvar; //this is a reference
pVar; // this is a pointer

//To get pointer from the reference you need to get an address.
&refVar; //this is a pointer (an address)

// To get a reference from pointer you need to derefecence it
*pVar; // this is a reference!

Итак, теперь должно быть понятно, почему "экземпляр" является ссылкой, а "this" является указателем (адресом) в вашем примере. Чтобы проверить, является ли это одним и тем же объектом, нам нужно получить адрес ссылочного "экземпляра" и сравнить его с указателем "this". Вот почему правильное сравнение

if(this == &instance) {}
  • 0
    Понял. большое спасибо
1

Сначала вы должны четко знать, что такое указатель. Указатель содержит адрес указанного типа данных.

В этом случае указатель "this" указывает на объект, созданный из ClassA, что означает, что "это" равно адресу объекта. Имея указатель, вы используете звездочку (*) перед указателем для доступа к объекту на что указывает.

Таким образом, "* this" - текущий экземпляр, а не его адрес.

(this == & instance) - это сравнение равенства между указателем (который является адресом текущего экземпляра) и адресом "instance".

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

Экземпляр - это не то же самое, что адрес экземпляра.

ClassA myObject; //myObject is an instance
ClassA * ptr;    //ptr is a pointer that only points to objects of ClassA 
ptr = &myObject; //&myObject is instance address, assign address of myObject to ptr
                 //in other words, make ptr point to myObject
(*ptr).someFunction(); //use asterisk to access object members
  • 0
    Понял. большое спасибо
1

Тестирование this == &instance проверяет самозадачу, то есть случай, когда операндом является сам объект:

Foo x;
x = x;   // or: x.operator=(x)

"Проблема" заключается в том, что C++ имеет очень плохое управление псевдонимом, и вы не можете знать или ограничивать, указывают ли какие-либо два указателя или ссылки на один и тот же объект. Поэтому вам нужно протестировать.

Для чего-то простого цельного числа ans самозапуск не будет огромным делом, но представьте себе базовый, наивный "умный указатель" (хотя это было бы не очень умно):

 struct TPtr
 {
     T * ptr;
     TPtr(T * p) : ptr(p) {}
     TPtr(TPtr const & rhs)  : ptr(new T(*rhs.ptr)) {}
     ~TPtr() { delete ptr; }

     TPtr & operator=(TPtr const & rhs)
     {
         delete ptr;
         ptr = new T(*rhs.ptr);   // uh-oh
     }
 };

Вы можете определить проблему?

  • 0
    Я знаю, что есть проблема с «удалить ptr», но почему бы не удалить себя (или сказать это)?
  • 0
    @ user1193710: Подумайте об этом: Что такое rhs.ptr ? Безопасно ли говорить *rhs.ptr когда rhs - это тот же объект, что и *this ?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню