2017-10-16 2 views
0

Je me demande s'il existe une classe C++ standard qui est l'équivalent d'un tailq. Je pourrais utiliser l'implémentation c d'un tailq, mais il utilise beaucoup de macros et est plutôt moche.Equivalent C++ de tailq

Fondamentalement, j'ai une classe, dont chaque instance doit faire partie de plusieurs listes. Pour éviter les déréférences de malloc/mémoire supplémentaires, j'aimerais stocker les pointeurs next et prev dans la classe elle-même. Est-ce que C++ a une façon intelligente de le faire, ou est-ce que je préfère utiliser <sys/queue.h>?

+5

Qu'est-ce qu'un 'tailq'? – Ron

+0

Donc, vous auriez besoin d'avoir un vecteur de pointeurs next/prev est-ce le cas? Vous pouvez simplement créer une structure simple qui encapsule votre classe et deux vecteurs, non? Ce que vous décrivez ne me semble pas clair. Peut-être que plus de contexte pourrait être utile. – AlexG

+0

Comment prévoyez-vous qu'un objet soit membre de plusieurs listes chaînées et qu'il stocke ses propres liens? Souhaitez-vous le stocker pour stocker une paire de liens séparée pour chaque liste? –

Répondre

1

En C++ Je voudrais avoir des conteneurs de shared_ptr. Peu importe, il peut être std::list ou std::vector ou n'importe quel conteneur. Parce qu'avec shared_ptr vous avez chaque élément séparément alloué, je ne vois aucune bonne raison d'utiliser std::list donc je pencherais pour std::vector<std::shared_ptr<X>>

Exemple:

#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'; 
} 

la sortie est:

-24 11 1024 5 
1024 -24 5 
0

Il n'y a aucun problème pour stocker des pointeurs de la classe à l'intérieur de lui-même. Le code suivant compile très bien:

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

Cela vous permettra d'avoir des pointeurs de plusieurs listes dans l'objet:

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

oui, mais alors pour parcourir la liste, vous devez utiliser 'offsetof()', pour obtenir le pointeur de classe d'origine ('next = current-> next - offsetof (courant, suivant)'), que je doute si cela fonctionnerait toujours comme prévu en C++. (Rappelez-vous qu'il existe plusieurs listes dans une classe). – user2766918

+0

@ user2766918 Vous pouvez avoir un vecteur de pointeurs next et prev, chacun correspondant à une liste différente. Réponse éditée pour refléter ceci –