5

Dieser Code ist ein vereinfachter Test für etwas, das ich woanders versuchen möchte. Ich habe eine Funktion, die ein "ref-to-ptr" -Argument nimmt und es ändert, um einen Zeiger von einer Liste von Zeigern zurückzugeben.Kann die Zuweisung von einer Dereferenzierung const_iterator zu undefiniertem Verhalten führen?

#include <iostream> 
#include <list> 
using namespace std; 

typedef int* intp; 
typedef std::list<intp> intplist; 
intplist myList; 

void func(intp &arg) // (1) 
{ 
    intplist::const_iterator it = myList.begin(); 
    std::advance(it, 2); 
    arg = *it; 
} 

int main() 
{ 
    myList.push_back(new int(1)); 
    myList.push_back(new int(2)); 
    myList.push_back(new int(3)); 

    int* ip = NULL; // (2) 
    func(ip); 
    if (ip) cout << "ip = " << *ip << endl; 
    else cout << "ip is null!" << endl; 

    for (intplist::const_iterator it = myList.begin(); it != myList.end(); ++it) 
     delete *it; 
    return 0; 
} 

Es funktioniert und druckt ip = 3 wie erwartet, nur ich bin besorgt, dass es nicht definiertes Verhalten verursachen kann oder sonst zu Problemen führen, weil ich die Konstantheit des Iterator am Abstreifen durch die Zuordnung des Ergebnis es dereferencing zu das Argument. Ich habe versucht, const bei (1) und (2) hinzuzufügen, aber es hat nicht gebaut.

Bin ich richtig besorgt zu sein? Wenn ja, warum bekomme ich keine Warnung von g ++ (4.9.2)?

+1

"Ich habe versucht, const bei (1) und (2) hinzuzufügen, aber es hat nicht gebaut.": Haben Sie auch füge 'const' zu' intp' typedef hinzu? – Petr

+0

Nein ... Ich behandelte das Typedef als ein dummes String-Ersetzungs-Makro und setzte das const einfach in die 'func'-Deklaration: 'void func (const intp & arg)'. Dein Weg, es baut und funktioniert, aber ich verstehe nicht, was der Unterschied ist. – neuviemeporte

+0

'intp' ist ein Zeiger. 'const intp' ist ein konstanter Zeiger, er sagt nichts über die Konstanz des Wertes aus, auf den er zeigt. Wenn Sie 'typedef const int * intp' sagen, sagen Sie, dass es auf eine const Ganzzahl zeigt. – Petr

Antwort

5

Der Code ist völlig in Ordnung. Sie entfernen keine Konstanz (es gibt keine Möglichkeit, dies implizit in C++ zu tun). *it gibt Ihnen eine const intp &. Du bist und kopierst den Zeiger, auf den sich diese Referenz bezieht, in arg. Das Kopieren von etwas entfernt die Konstanz nicht. Die Zuordnung zu arg ordnet in ip in Ihrem Fall, es nicht bind alles direkt an die Objekt im Container.

+0

Wenn ich das richtig lese, bedeutet das, dass "* es" ein Verweis auf einen Zeiger auf const int ist. Wie kann ich das dem Wert "val" zuweisen, der "Verweis auf Zeiger auf int" ist (nicht-const)? – neuviemeporte

+0

OK, ich glaube ich verstehe jetzt - es ist "const Verweis auf Zeiger-zu-Int", richtig? Der Zeiger war nie const. – neuviemeporte

+0

@neuviemeporte Ja, es ist eine "Referenz auf eine (Konstante (Zeiger auf int))". Klammern im mathematischen Sinne. – Angew

2

const_iterator bedeutet nur, dass Sie diesem Iterator nicht zuweisen können und/oder nur Const-Funktionen für das Objekt aufrufen können, auf das er zeigt. Es gibt kein Problem mit dem Kopieren der value - in diesem Fall ein Zeiger. Sie speichern keine const Zeiger, wenn Sie wären, dann müssten Sie einen const Zeiger zuweisen

Verwandte Themen