1

私は Python のバックグラウンドを持っているので、これについてはご容赦ください。私が探しているものと同等のPythonを提供しますが。

ネットワーク ノードのリストを作成しているので、それらの 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);、クラス宣言の後に試みましたが、どちらの方法でも、ベクトルが宣言されているか、またはその逆で、Node クラスは NodeList ベクトルを認識していません。

これを行う方法はありますか?タイプがそのクラスの既存のベクトルに追加する自己参照クラスになります。

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 に答える