Изменить 'this' указатель объекта на объект другого объекта

class C{
   //methods and properties
}

void C::some_method(C* b){
    delete this;
    this = b;     
}

Это дает мне ошибку при компиляции:

error: lvalue required as left operand of assignment

Мое намерение: Скажем, есть объекты a и b класса C. содержимое класса C может быть очень огромным, а полевое копирование может быть очень дорогостоящим. Я хочу, чтобы все содержимое "a" было заменено на b экономичным способом.

Будет ли конструктор копирования по умолчанию выполнить задание?

Я нашел что-то под названием "move constructor" http://akrzemi1.wordpress.com/2011/08/11/move-constructor/

Возможно, он может получить эффект, который я хочу.

Ответ 1

this -pointer - это неявный указатель на объект, в контексте которого вы работаете, его нельзя переназначить.

В соответствии с Библией Страуступа (язык программирования С++, 3-е издание, которое у меня есть) this выражается как

C * const this

означает, что у вас есть постоянный указатель на ваш класс C, поэтому компилятор будет жаловаться, если вы попытаетесь его изменить.

EDIT:

Поскольку я был исправлен, вышеупомянутое выражение не описывает this полностью правильно, поскольку this на самом деле является rvalue.

Ответ 2

Вы не можете изменить то, что указывает this. Я также не знаю, почему вы хотите это сделать.

Ответ 3

Чтобы процитировать стандарт:

В теле нестатической (9.3) функции-члена ключевое слово this - выражение prvalue, значение которого является адресом объект, для которого вызывается функция.

"prvalue" - это чистое значение, что-то вроде 42 или 3.14159. Точно так же вы не можете сделать что-то вроде 42 = x, вы не можете присваивать this; в обоих случаях (по крайней мере концептуально), там не является объектом, значение которого может измениться.

И мне действительно интересно узнать, что вы ожидаете, если Я пишу что-то вроде:

int
main()
{
    C c1;
    C c2
    c1.some_method( &c2 );
}

Ожидаете ли вы, что адрес c1 каким-то чудесным образом изменить, а для c1 и c2 - псевдонимы к одному и тому же объекту? (И c1.some_method( NULL ) еще более intreguing.)

Ответ 4

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

Кроме того, если вы попытаетесь сделать копию объекта, вы можете перезаписать operator=

class Foo
{
  public:
    [...]
    Foo& operator=(const Foo& foo);
}

int main()
{
 Foo foo;
 foobar = foo; //invoke operator= overwrited method
}


Ответ 5

Ошибка говорит: "Вы не можете назначить b на this". Насколько я знаю, this - это то, что вы не можете изменить, потому что это не фактический указатель, а самореклама.

Ответ 6

Просто используйте обычный подход вместо черной магии и UB:

C* c1 = new C();
C* c2 = new C();

// do some work perhaps ...

delete c1;
c1 = c2;

Теперь c1 является псевдонимом c2, как вы хотели. Будьте осторожны, хотя при очистке памяти, чтобы вы не удалили объект дважды. Возможно, вы можете рассмотреть умные указатели...