简体   繁体   English

作为静态类成员的对象向量

[英]Vector of objects as a static class member

I have a following snippet of code: 我有以下代码片段:

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) {
        }
};

What I want to achieve, is to print all instances of objects of class Person (name and surname, without position from class Worker) which exists at particular moment, so in example 我要实现的是打印在特定时刻存在的Person类的对象的所有实例(名称和姓氏,没有来自Worker类的位置),因此在示例中

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

should print only 应该只打印

aaa bbb
ccc ddd
ggg hhh

as only these objects exists at the moment of calling Person::OutputPersons. 因为在调用Person :: OutputPersons时仅存在这些对象。

What I don't know is how to project class Person fields. 我不知道如何投影类Person字段。 As you see, I have been trying to make a static vector which should "trace" all objects of Person - with adding an element in constructor and removing in destructor. 如您所见,我一直在尝试制作一个静态矢量,该矢量应该“跟踪” Person的所有对象-在构造函数中添加一个元素,在析构函数中删除。 I only have a problem with type of elements in this vector, as I cannot put there any kind of pointer to class Person object. 我只对矢量中的元素类型有问题,因为我不能在其中放置任何指向类Person对象的指针。

EDIT: 编辑:

As I get known it's legitimate to have a vector of Person*, I modified my code 我知道拥有一个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);
        }

but I'm getting error "undefined reference to 'Person::tracer_'. What am I doing wrong? 但我收到错误消息“对'Person :: tracer_'的引用未定义。我在做什么错?

To answer your comment, yes, it is perfectly valid to have pointers to a class a data members in your class. 要回答您的评论,是的,在类中具有指向数据成员的类的指针是完全有效的。

However, there are a few modifications that you need to make to your code. 但是,您需要对代码进行一些修改。 For instance, in your setup the "ggg hhh" Person is not displayed because it is a temporary object whose destructor is called immediately after it is passed to the function. 例如,在您的设置中,不会显示“ ggg hhh” Person,因为它是一个临时对象,其析构函数在传递给函数后立即被调用。 In order to catch this object, you have to add a user-defined copy-constructor to catch the object created in the function: 为了捕获该对象,您必须添加一个用户定义的复制构造函数以捕获在函数中创建的对象:

#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) 
    {

    }
};

To answer your new question, you must define tracer_outside of your class like this: 要回答您的新问题,您必须像这样定义类的tracer_outside:

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

That's just how static class variables work in C++. 这就是静态类变量在C ++中的工作方式。

With these modifications, the output is: 经过这些修改,输出为:

aaa bbb
ccc ddd
ggg hhh

Note: it would probably be a better design for Worker to inherit from Person rather than maintain a Person field. 注意: WorkerPerson继承而不是维护Person字段可能是一个更好的设计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM