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

时间:2013-07-17 19:21:30

标签: c++ class

我来自Python背景,请原谅我。虽然我会提供与我正在寻找的Python等价的东西。

我正在创建一个网络节点列表,所以我想创建一个类“Node”,它存储它们的MAC,IP地址和主机名,以及一个可以打印出来的函数。以下是我的代码:

#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();
}

当我运行它时会打印出来:

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

我想要的是在创建时将这些对象自动添加到名为NodeList的向量中。例如,以下是我在Python中的表现:

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

我尝试了类似的举动,我把这条线放在一边: 在类声明之前vector<Node> NodeList;(并且NodeList.push_back(this);作为Public函数),并在类声明之后尝试,但是无论哪种方式,编译器在声明向量时都不知道Node类,反之亦然,Node类不知道NodeList向量。

有办法做到这一点吗?它将是一个自我引用类,附加到类型属于该类的现有向量。

3 个答案:

答案 0 :(得分:3)

当然:在类中声明并定义一个静态成员,将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;

答案 1 :(得分:2)

明确地做:

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

答案 2 :(得分:1)

根据我的经验,由于必须在C ++中手动管理内存,因此这种设计通常不会很好。 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();
}

此解决方案的问题在于您是否有指向单个节点的指针。你最终可能会遇到悬空指针和内存损坏。

另一种解决方案是:

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

    // ...
}

此替代设计的问题是传递给NodeList的每个节点都将是该节点的新COPY。所以如果你这样做:

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]
}

更好的设计包括创建某种类型的 NodeManager 类,并通过此管理器创建和访问节点,这将控制所有节点对象的生命周期。