2013-07-17 49 views
1

我來自Python背景,所以請原諒我。雖然我會提供相當於我正在尋找的Python。將「this」添加到C++中的類實例化向量中

我正在創建一個網絡節點列表,所以我想創建一個類「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 

我想是有這些對象自動添加到一個叫做節點列表在創建載體。例如,這裏是我是如何做到這在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類,反之,Node類不知道NodeList向量。

有沒有辦法做到這一點?這將是自我參考類,追加到類型爲該類的現有向量。

+0

從設計的角度來看,這確實是一個壞主意。 –

+0

爲什麼?我是新的(呃)C++,請解釋一下。 – armani

+0

對於初學者來說,您正在創建一種綁定使用單個容器的類型,這意味着您將無法在同一個程序中定義多個網絡。還有其他問題(比如'list()',而不是慣用的'std :: ostream&operator <<(std :: ostream&,Node const&)'),在你的界面中完成的額外的字符串副本('set_values (std :: string,std :: string,std :: string)'),這兩個階段的構造(是否有意義有一個沒有IP的'Node'? –

回答

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

這種解決方案的問題是,如果你有指向indivual節點指針。你最終可能會發生懸掛指針和內存損壞。

和替代的解決方案是:

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

更好的設計涉及創建節點管理器類某種以及創建和通過該管理器,它會控制所有的節點對象的生命週期訪問節點。

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; 
2

做它明確:

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