1

I'm coming from a Python background, so forgive me on this one. Though I will provide the Python equivalent of what I'm looking for.

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. 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. For example, here is how I did that in 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; 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.

Is there a way to do this? It would be self-referencial class appending to an existing vector whose type is of that class.

4

3 回答 3

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;
于 2013-07-17T19:24:36.590 回答
2

明确地这样做:

   std::map<std::string, Node> map;
   map[mac1] = Node(mac1,...);
   map[mac2] = Node(mac2,...);
于 2013-07-17T19:27:04.620 回答
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的新副本。所以如果你这样做:

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类,并通过此管理器创建和访问节点,这将控制所有节点对象的生命周期。

于 2013-07-17T21:54:31.370 回答