2013-07-17 2 views
1

저는 파이썬 배경에서 왔으므로이 것에 대해 용서해주십시오. 비록 내가 찾고있는 것에 해당하는 파이썬을 제공 하겠지만.C++에서 클래스 인스턴스화시 벡터에 "this"를 추가하십시오.

네트워크 노드 목록을 만들고 있으므로 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를라는 벡터에 추가 이러한 개체를하는 것입니다 다음은 내 코드입니다.

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

가 나는 라인 넣어 유사한 이동, 시도 : (공용 함수와 NodeList.push_back(this);) 클래스 선언 이전 vector<Node> NodeList;을하고, 이후에 시도 예를 들어, 여기에 내가 파이썬에서 것을 한 방법이다 하지만 컴파일러는 벡터가 선언 될 때까지 Node 클래스를 인식하지 못합니다. 그 반대의 경우도 Node 클래스는 NodeList 벡터를 인식하지 못합니다.

이 방법이 있습니까? 이 클래스는 해당 클래스의 유형을 가진 기존 벡터에 추가하는 자체 참조 클래스입니다.

+0

이것은 디자인 관점에서 보면 정말 나쁜 생각입니다. –

+0

왜? 저는 C++에 대한 새로운 것입니다. 설명해주십시오. – armani

+0

처음에는 단일 컨테이너와 함께 사용하도록 바인딩 된 유형을 작성하고 있습니다. 즉, 동일한 프로그램에서 여러 네트워크를 정의 할 수 없습니다.관용적 인'std :: ostream & operator << (std :: ostream &, Node const &)') 대신에'list()'와 같은 다른 이슈들, 당신의 인터페이스 (set_values (std :: string, std :: string, std :: string)'), 2 단계 구조 (IP가없는'Node'를 갖는 것이 합리적입니까? –

답변

1

, 디자인의이 종류의 것이다 종종 C++로 수동으로 메모리를 관리해야하기 때문에 잘 끝나지 않습니다. this은 개체에 대한 원시 포인터이며 관리되지 않습니다.

이 작업을 수행 할 수 있습니다 : 당신이 indivual 노드를 가리키는 포인터가있는 경우이 솔루션을

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 클래스를 생성하고, 생성하고 모든 노드 객체의 수명을 제어하는 ​​것이 매니저를 통해 노드를 액세스 포함한다.

3

은 물론 :

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

명시 적으로 수행합니다 : 그것은 위에 this 포인터를 밀어 선언하고 클래스의 정적 멤버를 정의 내 경험에

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