Постоянный указатель на родителя - PullRequest
0 голосов
/ 20 марта 2011

Как я могу использовать this в качестве постоянного указателя, чтобы он работал вне текущей области видимости?

Что касается этого примера, я не знаю, как мне установить fx.parent:

class Effect
{
    Card* parent;
};

class Card
{
    vector<Effect> effects;
    void addEffect(Effect);
};

Card::addEffect(Effect fx)
{
    /*
     * the `this` pointer is not persistent and
     * will not work outside of this scope
     */
    fx.parent = this; 
    this->effects.push_back(fx);
}

PS: Я был бы благодарен за любую литературу о том, когда указатели уничтожаются, становятся недействительными и т. Д. Я не мог найти что-нибудь читаемое.Вообще-то, вообще ничего.

Ответы [ 4 ]

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

Указатель this объекта аналогичен получению адреса:

#inclide <iostream>

class X{
public:
    X* GetThis(){
        return this;
    }
};

int main(){
    X x;
    X* addr_x = &x;
    X* this_x = x.GetThis();
    if(addr_x == this_x)
        std::cout << "Both are the same" << std::endl;
    else
        std::cout << "Shouldn't happen" << std::endl;
}

Смотрите на Ideone. Таким образом, this - это просто обычный указатель на ваш класс со специальным именем, поэтому в вашем коде нет проблем с использованием this. Помимо этого, есть некоторые ошибки, например, отсутствующий тип возвращаемого значения в определении Card::addEffect и Card* parent в class Effect, являющийся частным, и как таковой он не может быть доступен для Card.

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

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

Card::addEffect(Effect fx)
{
    effects.push_back(fx);
    effects.back().parent = this;
}

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

Обратите внимание, что этот кодгенерирует другую копию из-за передачи по значению.Давайте избавимся от этого:

Card::addEffect(Effect const& fx)
{
    effects.push_back(fx);
    effects.back().parent = this;
}

Также обратите внимание, что как только емкость исчерпана, вектор выполнит внутреннее перераспределение, и все указатели станут недействительными.Самый простой обходной путь - зарезервировать достаточно места с самого начала:

Card::Card()
{
    effects.reserve(1000);   // never more than 1000 effects at once
}

Если это неприемлемо для вас, вы должны либо использовать другой контейнер (std::list<Effect>), либо поместить свои эффекты в кучу и управлять имивручную (std::vector<Effect*>) или с помощью умного указателя (std::vector<boost::shared_ptr<Effect> >).

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

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

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

Хорошо, так это выглядит так:

Прежде всего ключевое слово " this " означает текущий объект.
Итак, в этом контексте:

Card::addEffect(Effect fx)
{
    fx.parent = this; 
    this->effects.push_back(fx);
}

этот является объектом Card , в котором была вызвана функция addEffect () ..

Во-вторых, указатели не становятся недействительными или уничтожаются. Вы можете уничтожить объект, на который они указывают, используя оператор delete :

Blah* pointer = new Blah();
delete pointer;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...