Изменить указатель "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
экономичным способом.
Будет ли конструктор копирования по умолчанию выполнять поставленную задачу?
Я нашел что-то под названием "Переместить конструктор" http://akrzemi1.wordpress.com/2011/08/11/move-constructor/
Возможно, это может получить эффект, который я хочу.
6 ответов
this
-pointer - это неявный указатель на объект, в контексте которого вы работаете, вы не можете переназначить его.
Согласно Библии Страуструпа (Язык программирования C++, 3-е издание, которое у меня есть) this
выражается как
C * const this
Это означает, что у вас есть постоянный указатель на ваш класс C, поэтому компилятор будет жаловаться, если вы попытаетесь изменить его.
РЕДАКТИРОВАТЬ:
Как я исправил, вышеупомянутое выражение не описывает this
полностью правильно, для this
на самом деле значение.
Вы не можете изменить то, что this
указывает на. Я также не знаю, почему вы хотите это сделать.
Чтобы процитировать стандарт:
В теле нестатической (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 )
еще более интригующе.)
Вы не можете присвоить другое значение this
поскольку это указывает на сам объект, и это не имеет никакого смысла. Вы можете создать экземпляр нового объекта и использовать его неявный указатель this.
Более того, если вы попытаетесь сделать копию объекта, вы можете перезаписать operator=
class Foo
{
public:
[...]
Foo& operator=(const Foo& foo);
}
int main()
{
Foo foo;
foobar = foo; //invoke operator= overwrited method
}
Просто используйте обычный подход вместо черной магии и UB:
C* c1 = new C();
C* c2 = new C();
// do some work perhaps ...
delete c1;
c1 = c2;
Теперь c1 - это псевдоним c2, как вы и хотели. Будьте осторожны при очистке памяти, чтобы не удалить объект дважды. Вы могли бы, возможно, рассмотреть умные указатели...
Ошибка говорит: "Вы не можете назначить b
в this
". Насколько я знаю, this
это то, что вы не можете изменить, потому что это не фактический указатель, а ссылка на себя.