Supposons que je souhaite créer une liste liée non modifiable (c'est-à-dire qu'il ne peut être traversé qu'aucun nœud ne peut être ajouté ou supprimé une fois qu'il a été créé initialement). Cela pourrait être facilement mis en œuvre par: Ma question est de .... Serait-il possible d'utiliser des références au lieu des pointeurs? P> struct ListNodeConst
{
int value;
const ListNode* nextNode;
}
8 Réponses :
Jetez un coup d'œil à cet exemple par SBI, il semble fonctionner: https://stackoverflow.com/a/3003607/1758762
Pouvez-vous donner un exemple donner un exemple sur la façon d'utiliser cette classe? On dirait que de générer des nœuds un par un (dans un état invalide) et de les relier plus tard un par un.
Je pense que je comprends cette solution un peu plus. Mais le truc est essentiellement le truc de reculer des références par le truc du placement nouveau. Je ne sais pas si c'est UB, mais il défait le but d'utiliser des références comme des liens. Il les utilise essentiellement comme des pointeurs (rabindables).
non. Raisons: P>
Mauvais: 1 / La question concerne une liste non modifiable et 2 / / vous pouvez avoir le dernier élément provenant d'une superclasse sans référence NightNode.
Comment la liste se termine-t-elle? p>
Vous aurez besoin d'au moins deux types: la fin et non. Vous avez également besoin de gestion de la vie. Et soit de l'heure d'exécution ou de la connaissance statique de quel type. P>
Une implémentation totalement statique pourrait être effectuée, où chaque nœud est son propre type qui sait jusqu'où il est à la fin. P>
ou vous pouvez simplement avoir un tampon inticulé et créer des éléments hors de l'ordre inverse. P>
Un cercle est également possible. Faites que la première référence se réfère au dernier élément que vous construisez. P>
Ceci est typique d'un list em> dans les langages fonctionnels: Le truc est cependant, Pour y parvenir en C ++, vous pourriez Profitez de l'un des em> l'un des em> (mais ce n'est pas si bien soutenu) ou de polymorphisme em>. p> et ensuite: p> et maintenant, vous n'avez plus de problème de poulet et d'œuf; Démarrez simplement à partir d'une instanciation de Remarque: la présence de liste A code> est un complet Tapez et peut renvoyer
vide code> ou un autre nœud (c'est pourquoi il peut se terminer). P>
videylist
_Kind code> dans la classe de base n'est pas si OO, Mais cela rend les choses plus proches de l'exemple fonctionnel par marquage fort> quelle alternative est utilisée. em> p> p>
Ou juste boost :: variante
Strust ListNode
Emptylist Code> ne doit pas nécessairement être lié à
listbase
boost :: facultatif
@Yakk: Oui, Boost :: Facultatif
peut-être un code> et
boost :: variante
d'AB code> et les deux, en effet, permettent de se débarrasser de l'héritage. Ils sont également des concepts légèrement plus compliqués, je pense.
Comme @vlad dit, le problème des références est que vous aurez besoin d'un objet final.
La bonne nouvelle est que, en principe, vous pouvez toujours avoir une liste cyclique si vous avez une utilisation pour cela.
C'est une chose fondamentale, si l'élément "Suivant" est une référence non nullable signifie qu'il y a toujours un élément suivant, c'est-à-dire que la liste est infinie ou, plus de manière réaliste, elle se ferme sur elle-même ou dans une autre liste. Pris L'exercice est assez intéressant et Les éléments doivent vivre dans la pile et la liste est statique forte> (Eh bien, les références ne sont pas rabindables de toute façon) et les liens doivent être Il n'y a qu'un seul moyen de construire le noeud code> / list> / liste, c'est-à-dire pour le fermer avec lui-même (ou avec un autre nœud préexisant). La liste résultante est donc soit une forme circulaire ou "RHO". P> const code> références!
Finalement, la valeur code> peut être apportée, puis
mutable code> apparemment (probablement en sécurité?).
(À ce stade, on se demande comment se trouve-t-il différent des références d'une matrice de pile par un indices modulo.) P>
circular_list<int> l{1,2,3,4}; // couldn't do this for obscure reasons
Je pourrais être hors de la marque, mais cela fonctionne les tests habituels p> bien sûr, aussi longtemps que tous les nœuds Restez dans la portée, nous sommes tous ok ici. Sinon pas. Étrange et merveilleux. Utilitaire très limité? P> p>
C'était assez délicat, mais cela a fonctionné:
#include <iostream> #include <typeinfo> class Last { public: int x; int last; Last(int i) { std::cout << "parent constructor(" << i << ")\n"; x = i; last = 1; } }; struct fourptr { int v1, v2; void *p1, *p2; }; class chain : public Last { public: chain(int i) : Last(i) { std::cout << "child constructor(" << i << ")\n"; last = 0; } void viewandnext() { struct fourptr *fp = (struct fourptr *) this; std::cout << x << ", this = " << this << ", sizeof *this = "<< sizeof * this << ", * this = {" << fp->v1 << ", " << fp->v2 << ", " << fp->p1 << ", " << fp->p2 << "}" << "\n"; if (last == 0) ((chain &)next).viewandnext(); } Last & fn(int x) { Last * e = (x>0) ? new chain(x-1) : new Last(x-1); return *e; } Last & next = fn(x); // This is not a pointer but a reference }; int main(void) { chain &l = *(new chain(8)); std::cout << "sizeof l = "<< sizeof l << "\n"; l.viewandnext(); }
Un moyen simple d'éviter un problème de poulet-oeuf pour une liste avec des références consiste à rappeler que votre mémoire d'objet est allouée, alors votre constructeur est appelé. De plus, l'accès à NEAT WAY de résoudre ce problème: P> Ce pointeur code> est garanti à l'intérieur d'un constructeur par standard C ++.
struct node {
int data;
node& next;
node(node& n, int d): next(n), data(d) {}
};
node tl(tl, 69); // tl is already in the scope!
C'est un problème que si vous essayez d'insérer un nœud n'importe où à côté de la tête de la liste.
Comment allez-vous représenter le noeud final? La référence ne peut pas être nulle.
Comme @vlad a dit, le problème des références est que vous aurez besoin d'un objet final. La bonne nouvelle est que, en principe, vous pouvez toujours avoir une liste cyclique. Si vous avez une utilisation pour cela.