Изменение ЭТОГО - PullRequest
       35

Изменение ЭТОГО

2 голосов
/ 23 марта 2011

Есть ли способ изменить то, на что ЭТО указывает?

class foo{...}

foo* fooinstance = new foo();
foo* otherfooinstance = new foo();

void
foo::bar(){
    this = otherfooinstance;
}

fooinstance->bar();

для тех из вас, кто задается вопросом, в каком случае я бы изменил указатель this в этом случае.Я должен был сделать рекурсию дерева, где мне пришлось удалить промежуточные узлы .. для этого примера давайте предположим, что промежуточные узлы удаления имеют заголовок d.и эти промежуточные узлы имеют только одного ребенка.Таким образом, в нотации lisp, если у нас есть дерево, подобное

(g (d (i 4)) (i 5))

, функция removeIntermediates (tree) фактически приведет к тому, что выше

(g (i 4) (i 5))

и псевдокод для этого IF, если этот указатель был переназначен, будет выглядеть следующим образом ..

DTREE::removeIntermediates(){
    this = child(0); removeIntermediates();
}

TREE::removeIntermediates(){
    for each child { child->removeIntermediates();
}

Я хотел сделать это, не зная, что дочерний узел делает код разложенным на различные функции для каждого типа узла и имеет общую функцию для других типов.К сожалению, я только что закончил делать что-то вроде этого ..

TREE::removeIntermediates(){
    for each child { if(child->name == "d") {
        setchild(child->child(0));
        child->removeIntermediates();
    }
    else { child->removeIntermediates();}
}

Ответы [ 6 ]

8 голосов
/ 23 марта 2011

Нет, this нельзя изменить.

Концептуально это не имеет смысла, что вы пытаетесь достичь ?

2 голосов
/ 23 марта 2011

Стандарт C ++ запрещает присваивать этому значение в «9.3.2 Указатель this», указав, что «ключевое слово this является ненулевым выражением». Хотя некоторые компиляторы все еще разрешают присваивать это с помощью определенного переключателя времени компиляции, потому что в какой-то момент в ранних черновиках стандарт C ++ фактически разрешал присваивать «this».

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

2 голосов
/ 23 марта 2011

Нет, вы никогда не должны устанавливать this.

Если вам нужно указать на разные объекты, определите свою собственную переменную.

1 голос
/ 23 марта 2011

Нет. Это значение, а не значение. Самый простой способ думать это то, что он вызывает магию компилятора для доступа к объекту на которую функция была вызвана. Вы не можете изменить это больше чем вы могли бы изменить константу 3.

Исторически в очень ранних версиях C ++ вы могли изменить это, но только в конструкторе, и только как первое, что в конструктор: функциональность, предлагаемая этим, была добавлен пользовательским оператором new. Это было 20-15 лет назад, однако.

Что ты пытаешься сделать? Если вы просто хотите получить доступ к двум разные объекты из той же функции-члена, это не проблема: otherfooinstance-> должно работать, и даст вам доступ к частным пользователям.

0 голосов
/ 23 марта 2011

Указатель "this" на самом деле не существует. То есть он не хранится где-то вместе с объектом. Скорее, когда метод вызывается для объекта, компилятор передает адрес объекта в качестве дополнительного аргумента. Таким образом, «это» действительно появляется в стеке только во время выполнения метода.

Таким образом, даже если вы присвоите «this», как в вашем примере, ваше перенаправление на otherfooinstance будет продолжаться только в течение текущего вызова bar ().

0 голосов
/ 23 марта 2011

Метод-член void foo :: bar () {this = otherfooinstance; } будет скомпилирован так:

void foo__bar (foo * const this) {this = otherfooinstance; }

this является постоянным указателем на вызов экземпляра foo, поэтому вы не можете его изменить. И изменить это не очень хорошая идея.

...