2015-10-21 8 views
23

Mam funkcję, która przyjmuje odniesienie const jako argument. Nie powinien zmieniać argumentu, ale robi to (zmienna "_isVertex"). Jak to może zostać naprawione? Oto kod:Zmiany funkcji const obiekt

#include <vector> 
#include <iostream> 

using namespace std; 

class Element 
{ 
public: 
    bool isVertex() const 
    { return _isVertex; }; 

private: 
    bool _isVertex = true; 
}; 

class ElementContainer : public vector <Element> 
{ 
public: 
    void push(const Element &t) 
    { 
     // here everything is fine 
     cerr << t.isVertex() << ' '; 
     push_back(t); 
     // and here _isVertex is false, should be true! 
     cerr << t.isVertex() << '\n'; 
    } 
}; 

int main() 
{ 
    ElementContainer vertex; 

    vertex.push({}); 
    vertex.push(vertex[0]); 
} 
+0

Plus: masz mnie. Zauważ, że kontenery biblioteki standardowej C++ nie zostały zaprojektowane jako klasy bazowe. – Bathsheba

+0

'const' na końcu deklaracji funkcji gwarantuje tylko, że stan klasy nie zmieni się w wyniku wywołania funkcji. Zwrócona wartość nie jest stała i może być zmieniona po fakcie. –

Odpowiedz

32

Rozważmy uważnie vertex.push(vertex[0]);. t w funkcji push jest stałym odniesieniem do vertex[0].

Ale po push_back zawartość wektora została przesunięta (z powodu realokacji pamięci), a zatem vector[0] została przeniesiona gdzie indziej. t jest teraz zwisającym numerem referencyjnym.

To jest niezdefiniowane zachowanie. Boom.

+0

Warto zauważyć, że najwyraźniej 't' jest wypychane do nowo przydzielonego sklepu z zapasami _ po tym, że istniejące dane są kopiowane, a stary zapasowy sklep jest zwalniany. – imallett