2017-10-16 5 views
0

Ich frage mich, ob es eine Standard C++ - Klasse gibt, die einem Schwanz entspricht. Ich könnte die c-Implementierung eines Tailq verwenden, aber es verwendet viele Makros und ist etwas hässlich.C++ entspricht Schwanz

Grundsätzlich habe ich eine Klasse, die jede Instanz Teil mehrerer Listen sein muss. Um zusätzliche Dereferenzierungen von mallocs/memory zu vermeiden, möchte ich die Zeiger next und prev innerhalb der Klasse selbst speichern. Hat C++ einen cleveren Weg dies zu tun, oder bin ich besser dran, einfach <sys/queue.h> zu verwenden?

+5

Was ist ein 'tailq'? – Ron

+0

Sie müssten also einen Vektor von next/prev Zeigern haben? Sie können einfach eine einfache Struktur erstellen, die Ihre Klasse und zwei Vektoren kapselt, nein? Was du beschreibst, scheint mir nicht klar zu sein. Vielleicht könnte ein weiterer Kontext wertvoll sein. – AlexG

+0

Wie planen Sie, dass ein Objekt Mitglied mehrerer verknüpfter Listen ist und seine eigenen Links speichert? Möchten Sie ein separates Linkpaar für jede Liste speichern? –

Antwort

1

In C++ hätte ich Container von shared_ptr. Es ist egal, es kann std::list oder std::vector oder irgendein Behälter sein. Denn mit shared_ptr haben Sie jedes Element separat zugewiesen, ich sehe keinen guten Grund std::list zu verwenden, so würde ich mich für std::vector<std::shared_ptr<X>>

Beispiel:

#include <memory> 
#include <vector> 
#include <iostream> 

struct X { int a = 0; X() = default; X(int p) { a = p; } }; 

auto operator<<(std::ostream& os, X x) -> std::ostream& 
{ 
    os << x.a; 
    return os; 
} 

int main() 
{ 
    auto x1 = std::make_shared<X>(24); 
    auto x2 = std::make_shared<X>(11); 
    auto x3 = std::make_shared<X>(1024); 
    auto x4 = std::make_shared<X>(5); 

    std::vector<std::shared_ptr<X>> v1 = {x1, x2, x3, x4}; 
    std::vector<std::shared_ptr<X>> v2 = {x3, x1, x4};  

    // modify an object and observe the change in both lists 
    x1->a = -24; 

    for (const auto& e : v1) 
     std::cout << *e << ' '; 
    std::cout << '\n'; 

    for (const auto& e : v2) 
     std::cout << *e << ' '; 
    std::cout << '\n'; 
} 

der Ausgang ist:

-24 11 1024 5 
1024 -24 5 
0

Es gibt kein Problem, Zeiger der Klasse in sich selbst zu speichern. Der folgende Code kompiliert just fine:

class A 
{ 
    A* next; 
    A* prev; 
}; 

Dies ermöglicht es Ihnen innerhalb der Objektzeiger für mehrere Listen haben:

class A 
{ 
    std::vector<A*> next; 
    std::vector<A*> prev; 
}; 
+0

ja, aber dann, um die Liste zu gehen, müssen Sie die 'offsetof()', um den ursprünglichen Klassenzeiger ('next = aktuelle-> nächste - offsetof (aktuelle, nächste)' zu bekommen), was mir zweifelhaft ist, ob es in C++ immer wie erwartet funktionieren würde. (Denken Sie daran, dass es mehrere Listen innerhalb einer Klasse gibt). – user2766918

+0

@ user2766918 Sie können einen Vektor für die Zeiger next und prev haben, die jeweils einer anderen Liste entsprechen. Bearbeitete Antwort, um das zu reflektieren –