2013-12-06 2 views
0

У меня есть следующий фрагмент кода:Вектор объектов как статический член класса

class Person { 
     std::string name_; 
     std::string surname_; 
     //static vector<???> tracer_; 
    public: 
     Person(std:: string name, std::string surname) 
      : name_(name) 
      , surname_(surname) { 
       //something with tracer_ 
     } 
     ~Person() { 
      //something with tracer_ 
     } 
     static void OutputPersons(std::ostream& out) { 
      //print every element in tracer_ 
     } 
}; 

class Worker { 
     Person person_; 
     std::string position_; 
    public: 
     Worker(const Person& person, std::string position) 
      : person_(person) 
      , position_(position) { 
     } 
}; 

То, что я хочу добиться, чтобы напечатать все экземпляры объектов класса Person (имя и фамилию, без позиции от класс рабочий), который существует в определенный момент, так что в примере

Person s("aaa", "bbb"); 
Person t("ccc", "ddd"); 
{ 
    Person u("eee", "fff"); 
} 
Worker w(Person("ggg","hhh"),"guard"); 
Person::OutputPersons(std::cout); 

должен печатать только

aaa bbb 
ccc ddd 
ggg hhh 

как только эти объекты существуют в момент вызова Person :: OutputPersons.

Что я не знаю, как проецировать поля класса Person. Как вы видите, я пытался создать статический вектор, который должен «трассировать» все объекты Person - с добавлением элемента в конструктор и удалением в деструкторе. У меня только проблема с типом элементов в этом векторе, так как я не могу поместить туда никакого указателя на объект класса Person.

EDIT:

Как я получаю знать, что это законно, чтобы иметь вектор Person *, я изменил мой код

class Person { 
     std::string name_; 
     std::string surname_; 
     static std::vector<Person *> tracer_; 
    public: 
     Person(std:: string name, std::string surname) 
      : name_(name) 
      , surname_(surname) { 
      tracer_.push_back(this); 
     } 

, но я получаю ошибку «неопределенная ссылка на«Человека :: tracer_ ». Что я делаю неправильно?

+3

Почему бы и нет? std :: vector - совершенно законный тип. –

+0

Или 'std :: vector '. Указатель, который вам нужен, это 'this'. – leewz

+0

Насколько корректно использовать указатель на класс A в качестве члена класса A? Я этого не знал, но если это правда, моя проблема решена. –

ответ

3

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

Однако, re - несколько изменений, которые необходимо внести в ваш код. Например, в вашей настройке персонаж «ggg hhh» не отображается, потому что это временный объект, деструктор которого вызывается сразу же после его передачи в функцию. Для того, чтобы поймать этот объект, вы должны добавить определенный пользователем копировать-конструктор, чтобы поймать объект, созданный в функции:

#include <iostream> 
#include <algorithm> 
#include <vector> 

class Person 
{ 

private: 

    std::string name_; 
    std::string surname_; 

    static std::vector<Person*> tracer_; 

public: 

    Person(std:: string name, std::string surname) 
     : name_(name), 
      surname_(surname) 
    { 
     tracer_.push_back(this);  //add the person 
    } 

    //copy constructor 
    Person(const Person& p) : name_(p.name_), surname_(p.surname_) 
    { 
      tracer_.push_back(this);     //add the person 
    } 

    ~Person() 
    { 
     tracer_.erase(std::remove(tracer_.begin(), tracer_.end(), this), tracer_.end());        //remove the person, little messy 
    } 

    static void OutputPersons(std::ostream& out) 
    { 
     for (std::vector<Person*>::iterator it = tracer_.begin(); it != tracer_.end(); it++)    //iterate through vector and print all members 
     { 
      out << (*it)->name_ << ' ' << (*it)-> surname_ << '\n'; 
     } 
    } 
}; 

class Worker 
{ 
private: 

    Person person_; 
    std::string position_; 

public: 

    Worker(const Person& person, std::string position) 
     : person_(person), 
      position_(position) 
    { 

    } 
}; 

Чтобы ответить на ваш новый вопрос, вы должны определить tracer_outside вашего класса, как это:

std::vector<Person*> Person::tracer_; 

Вот как работают переменные статического класса на C++.

С учетом этих изменениями, выход:

aaa bbb 
ccc ddd 
ggg hhh 

Примечанием: это, вероятно, будет лучше дизайном для Worker наследовать от Person, а не поддерживать Person поля.

Смежные вопросы