对象矢量作为静态类成员

时间:2013-12-06 19:45:53

标签: c++ oop

我有以下代码片段:

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(名称和姓氏,没有来自类Worker的位置)的对象的所有实例,所以在示例中

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对象。

编辑:

我知道拥有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);
        }

但是我收到错误“对'Person :: tracer_'的未定义引用。我做错了什么?

1 个答案:

答案 0 :(得分:3)

要回答您的评论,是的,将类指针指向您班级中的数据成员是完全有效的。

但是,您需要对代码进行一些修改。例如,在您的设置中,不显示“ggg hhh”Person,因为它是一个临时对象,其析构函数在传递给函数后立即被调用。为了捕获这个对象,你必须添加一个用户定义的拷贝构造函数来捕获函数中创建的对象:

#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字段可能是更好的设计。