2016-05-20 8 views
1

У меня есть этот класс:указатели между элементами вектора <unique_ptr <myclass>>

#include <iostream> 
#include <string> 
#include <vector> 
#include <memory> 

using namespace std; 

class person 
{ 
public: 
    person(string name, string surname):_name(name), _surname(surname){} 
    virtual ~person(){} 
    void print() 
    { cout << _name << ' ' << _surname << endl 
     << "mother: " << _mother->get_name() << ' ' << _mother->get_surname() << endl 
     << "father: " << _father->get_name() << ' ' << _father->get_surname() << endl; 
    } 
    string get_name(){return _name;} 
    string get_surname(){return _surname;} 

    void set_parents(person &mother, person &father) 
    { 
     _mother = unique_ptr<person>(&mother); 
     _father = unique_ptr<person>(&father); 
    } 
private: 
    string _name, _surname; 
    unique_ptr<person> _mother, _father; 
}; 

, а затем основная функция:

int main() 
{ 
    vector<unique_ptr<person> > people; 
    vector<unique_ptr<person> >::iterator iter; 

    people.push_back(unique_ptr<person>(new person("Marisa", "Miller"))); 
    people.push_back(unique_ptr<person>(new person("Andrew", "Clark"))); 
    people.push_back(unique_ptr<person>(new person("Thomas", "Clark"))); 
    people.push_back(unique_ptr<person>(new person("Elisa", "Clark"))); 
    people.push_back(unique_ptr<person>(new person("Edward", "Drake"))); 
    people.push_back(unique_ptr<person>(new person("Jhon", "Drake"))); 

    // here is the problem: 
    people.at(2).set_parents(???) 

    for(iter = people.begin(); iter != people.end(); ++iter) 
    { 
     (*iter)->print(); 
    } 

    return 0; 
} 

Через указатели, я бы определил следующую родословную:

[Marisa Miller]  [Andrew Clark] 
     |     | 
     +---------+---------+ 
        | 
        +--------------[Thomas Clark] 
        | 
        +--------------[Elisa Clark]  [Edward Drake] 
             |     | 
             +---------+---------+ 
               | 
              [Jhon Drake] 

Вопрос: Как установить указатели ()и _father, через функцию get_parents(...)) к предыдущему элементу, содержащемуся в векторе? get_parents() функция также может быть определена как:

void get_parents(person* mother, person* father) 

или

void get_parents(unique_ptr<person> mother, unique_ptr<person> father) 

Спасибо за любые предложения

ответ

0

Уникальный указатель существует так, что указатель находится только в основном на одном месте все время. У вас более 1 ссылки (в векторе и, возможно, в Лице, если это отец или мать).

Вы можете посмотреть в использовании общих указателей и слабые указатели: http://en.cppreference.com/w/cpp/memory/shared_ptr http://en.cppreference.com/w/cpp/memory/weak_ptr

0

person не должен владеть _mother и _father.

Это, вероятно, лучше:

// ... 
private: 
    std::string _name, _surname; 
    person *_mother; 
    person *_father; 
}; // class person 

Теперь, если вы держите std::vector<std::unique_ptr<person>> people; (т.е. контейнер имеет свои элементы), вы могли бы написать:

void person::set_parents(person &mother, person &father) 
{ 
    _mother = &mother; 
    _father = &father; 
} 

people[2]->set_parents(*people[0], *people[1]); 
people[3]->set_parents(*people[0], *people[1]); 
people[5]->set_parents(*people[3], *people[4]); 

также закрепить функцию члена person::print (он выходит из строя в случае отсутствия родителей).