简体   繁体   English

在C ++中将“ this”添加到类实例化的向量中

[英]Add “this” to a vector on class instantiation in C++

I'm coming from a Python background, so forgive me on this one. 我来自Python背景,因此请原谅我。 Though I will provide the Python equivalent of what I'm looking for. 尽管我将提供与我要寻找的Python等效的工具。

I'm creating a list of network nodes, so I wanted to create a class, "Node", that stores their MAC, IP address, and Hostnames, along with a function that prints them out prettily. 我正在创建一个网络节点列表,因此我想创建一个类“ Node”,该类存储它们的MAC,IP地址和主机名,以及一个将它们打印得很漂亮的函数。 The following is my code: 以下是我的代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Node {
    string MAC, IP, Hostname;
    public:
        void set_values(string M, string I, string H);
        string list() {return "MAC: "+MAC+"\nIP: "+IP+"\nHostname: "+Hostname+"\n";}
};

void Node::set_values(string M, string I, string H) {
    MAC = M;    
    IP = I;     
    Hostname = H;
}

int main(int argc, char* argv[])
{
    Node firstnode;
    firstnode.set_values("C0:FF:EE:C0:FF:EE","192.168.1.60","My-PC");
    cout<<firstnode.list();
}

Which prints this out when I run it: 当我运行它时可以打印出来:

MAC: C0:FF:EE:C0:FF:EE
IP: 192.168.1.60
Hostname: My-PC

What I want is to have these objects automatically added to a vector called NodeList upon creation. 我想要的是在创建时将这些对象自动添加到称为NodeList的向量中。 For example, here is how I did that in Python: 例如,这是我在Python中执行的操作:

RecordersList=[]
class Recorder:
    def __init__(self, ARecorder, BRecorder, CRecorder):
        self.ARecorder = ARecorder
        self.BRecorder = BRecorder
        self.CRecorder = CRecorder
        RecordersList.append(self)

I tried a similar move, where I put the line: vector<Node> NodeList; 我尝试了类似的操作,在其中放置了一行: vector<Node> NodeList; before the class declaration (and NodeList.push_back(this); as a Public function), and tried after the class declaration, but either way the compiler isn't aware of the Node class by the time the vector is declared, or vice versa the Node class isn't aware of the NodeList vector. 在类声明之前(和NodeList.push_back(this);作为Public函数),并在类声明之后进行尝试,但是无论哪种方式,编译器在声明矢量时都不知道Node类,反之亦然Node类不知道NodeList向量。

Is there a way to do this? 有没有办法做到这一点? It would be self-referencial class appending to an existing vector whose type is of that class. 这将是自引用类,附加到类型属于该类的现有向量上。

Sure: declare and define a static member in the class, push the this pointer onto it: 当然:在类中声明并定义一个静态成员,将this指针压入该成员:

class Foo; // forward declaration to make vector happy

class Foo {
    private:
        static std::vector<Foo *> store;
    public:
        Foo() { store.push_back(this); }
};

std::vector<Foo *> Foo::store;

Do it explicitly: 明确地做:

   std::map<std::string, Node> map;
   map[mac1] = Node(mac1,...);
   map[mac2] = Node(mac2,...);

In my experience, this sort of design will often not end well due to having to manually manage memory in C++. 以我的经验,由于不得不手动管理C ++中的内存,这种设计通常无法很好地完成。 this is a raw pointer to the object and it is not managed. this是指向对象的原始指针,并且不受管理。

You can do this: 你可以这样做:

class Node; // forward declaration
std::vector<Node*> NodeList;

class Node
{
public:

    Node()
    {
        NodeList.push_back(this); // pass a POINTER to this object
    }
};

int main(int argc, char* argv[])
{
    Node* node1 = new Node(); // allocated a Node
    Node* node2 = new Node(); // allocated a Node

    // ...

    // deallocate ALL nodes
    std::vector<Node*>::iterator it = NodeList.begin();
    while (it != NodeList.end())
    {
        delete *it;
        ++it;
    }

    NodeList.clear();
}

The problem with this solution is if you have pointers pointing to indivual nodes. 该解决方案的问题是,如果您有指向单个节点的指针。 You could end up with dangling pointers and memory corruption. 您最终可能会悬空指针和内存损坏。

And alternative solution is: 替代解决方案是:

class Node
{
public:

    Node();
};

std::vector<Node> NodeList;

Node::Node()
{
    NodeList.push_back(*this); // pass a REFERENCE to this object
}

int main(int argc, char* argv[])
{
    Node node1; // create a node
    Node node2; // create a node

    // ...
}

The problem with this alternative design is that each node passed to NodeList will be a new COPY of that node. 这种替代设计的问题在于,传递给NodeList每个节点都是该节点的新COPY。 So if you do: 因此,如果您这样做:

int main(int argc, char* argv[])
{
    Node node1; // NodeList[0] is logically equal to node1

    node1.DoStuffThatModifiesTheContent();

    // At this point, node1 is no longer a logical equivalent of NodeList[0]
}

A better design would involve creating a NodeManager class of some sort, and creating and accessing nodes through this manager, which would control the lifetime of all the node objects. 更好的设计包括创建某种NodeManager类,并通过该管理器创建和访问节点,这将控制所有节点对象的生存期。

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

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