2015-07-02 3 views
1

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

То, что я пытаюсь выяснить это:

class Unit { 

public: 
    static vector< Unit* > Units_array; 
    static Unit* Last_created_unit; 

    Unit(); 

    Unit(string,int,int); 

private: 
some private vars 
} 

и чем я есть .cpp файл с определениями, а также. Я хочу знать: когда я вызываю конструктор, есть способ сохранить новый объект в переменной Last_created_unit или нажать его в Units_array. Я думал, что было бы лучше использовать указатели, потому что я хочу, чтобы это просто указатель на фактический новый объект, который я создал. Но когда я начинаю изменять члены объекта, он действует, как будто у меня два разных объекта, потому что в нем есть разные значения.

Unit::Unit(string name, int GUID, int faction){ 

    Last_created_unit = this; 
} 

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

Я хотел бы сделать что-то вроде следующего, но прямо в конструкторе.

Last_created_unit = new Unit("some_name", 1, 1); 

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

Я покажу вам путь его действия

//create new object 
Unit player = Unit("something",100,1); 
//our line Last_created_unit = this; have its value from constructor, seems fine. 
//than we change, for example int Health (Default 100) through our function SetHealth() 
Last_created_unit->SetHealth(90); 
//than we retrieve our Health GetHealth() 
player.GetHealth(); // output = 100 
Last_created_unit->getHealth() // output = 90 

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

Спасибо за помощь.

+0

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

+0

Я не могу воспроизвести вашу проблему здесь: https://ideone.com/lJVKUR –

+0

«Когда я вызываю конструктор» - ** вы? ** Вы уверены, что имели в виду «звонок»? –

ответ

2

Когда вы пишете

Unit player = Unit("something",100,1); 

вы (формально) создание временного объекта, который затем копируется в player. (Эта копия может быть удалена в зависимости от уровней оптимизации, но она все еще встречается в целях контроля доступа.)

Если для вас важна идентификация объекта, вы должны удалить конструктор копирования и разместить все экземпляры класса в интеллектуальных указателях:

Unit(Unit const&) = delete; 

// ... 

auto player = std::make_unique<Unit>("something",100,1); 
+0

Или без умных вещей, 'Unit player = Unit (« something », 100,1);' ===> 'Unit * player = new Unit (« something », 100,1);' –

+0

С умным материалом я думаю, если вы не хотите беспокоиться о вещах, связанных с делом. – Robinson

+0

О, я согласен, но есть разница между объяснением того, что пошло не так, и тем, что должно быть сделано вместо –

3

Создайте фабрику, которая создает объекты, и дайте фабрике отслеживать созданные объекты.

class Factory { 
    Unit* createUnit() { 
    Unit *newUnit = new Unit(); 
    // keep track of new objects 
    return newUnit 
    } 
}; 

class Unit { 
    friend Factory 
    protected: 
    Unit(); 
}; 
+1

Я согласен, но, возможно, простая статическая функция-член, например. 'static Unit * Unit :: createUnit() {...};', уже достаточно (меньше накладных расходов). – nils

0

Вы можете сохранить последний созданный объект в статическом list, к которому с т е р push_back последний созданный объект, а dtor удаляет его:

#include <list> 
#include <iostream> 
#include <algorithm> 


using namespace std; 


class Unit 
{ 
public: 
    Unit() 
    { 
     m_units.push_back(this); 
    } 

    ~Unit() 
    { 
     m_units.erase(find(m_units.begin(), m_units.end(), this)); 
    } 

private: 
    static list<Unit *> m_units; 
}; 


list<Unit *> Unit::m_units; 


int main() 
{ 

} 

Некоторые пункты заметить:

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

Эта линия

Unit player = Unit("something",100,1); 

означает создать новый временный объект, и ваш конструктор вызывается. Затем вы назначаете временный объект player с использованием созданного по умолчанию копирования-конструктора, который не отслеживает player в Last_created_unit. Затем временный объект (все еще отслеживаемый в Last_created_unit) уничтожается, поэтому любые последующие операции с использованием указателя Last_created_unit вызывают неопределенное поведение.

Вы должны построить новый объект так:

Unit player("something", 100, 1); 
0

Вы не используете Unit::Last_created_unit члена:

Unit::Last_created_unit->SetHealth(90); 
player.GetHealth(); 
Смежные вопросы