Ich bin ein CustomVector Klasse Schreiben intern Speichern von Daten eines Standard-Vektor unter Verwendung von:C++ Writing const Vektoren mit Zeigern auf non const
template <class T>
class CustomVector {
friend class CustomVector_ref<T>;
public:
...
private:
std::vector<T> _data;
};
Dann wird, um Subvektoren von CustomVector zu extrahieren, verwende ich eine Klasse Speichern von Zeigern auf jedes Element der Daten:
template <class T>
class CustomVector_ref {
public:
//Returns the value stored in CustomVector
//and pointed-to by _data_ref
T& operator[] (size_t id) { return *_data_ref[id] }
const T& operator[] const (size_t id) { return *_data_ref[id] }
...
private:
std::vector<T*> _data_ref;
};
, Jetzt ist mein Problem zu veranschaulichen, genügt die einfache costructor Aufbau eines Verweises auf alle Elemente der CustomVector
zu berücksichtigenDas funktioniert gut, aber wenn ich ein const CustomVector haben, ich brauche auch den Konstruktor zu definieren:
template<class T>
CustomVector_ref<T>::CustomVector_ref(const CustomVector<T>& cv)
{
for (const T& el : cv._data)
_data_ref.push_back(const_cast<T*>(&el));
}
Das funktioniert auch, aber wenn das CustomVector_ref Objekt nicht als const deklariert, dann mit dem nicht -const operator [] Es ist möglich, Daten in das const CustomVector-Objekt zu schreiben.
const CustomVector<int> cv(...) //CostumVector is somehow constructed,
//that does not matter now
std::cout<<cv[0]<<std::endl; //output 1 for example
CustomVector_ref<int> cvr(cv)
cvr[0] = 2;
std::cout<<cv[0]<<std::endl; //now cv[0] stores 2
Es ist möglich, dieses Verhalten zu vermeiden?
Ich habe bemerkt, dass dies geschieht auch mit Standardvektoren, beispielsweise
const std::vector<int> v(1,1);
std::vector<int*> vp;
vp.push_back(const_cast<int*>(&v[0]));
*vp[0] = 2;
std::cout<<v[0]<<std::endl; // now v[0] stores 2, not 1
Also, da dieser Standard C++, ich Mühe zu viel nicht meinen CustomVector zu beheben, aber es wäre schön zu wissen wenn es eine (nicht zu gewundene) Lösung gibt.
Sie müssen über die einfache Tatsache nachdenken, dass Standardbibliothekscontainer zwei verschiedene Iteratorklassen definieren: 'iterator' und' const_iterator'. Es gibt einen guten Grund dafür, und Sie haben gerade herausgefunden, was dieser Grund ist. Ihre Situation ist völlig analog. Sie müssen zwei verschiedene Referenzen implementieren, eine veränderbare und eine "konstante" Referenz. Für eine zusätzliche Gutschrift sollte die veränderbare Referenz auf die Referenz "const" umsetzbar sein, sodass sie an Funktionen übergeben werden kann, die "konstante" Referenzen als Argumente verwenden. –
Zögern, es als dupe zu kennzeichnen, aber das ist eng reeted https://stackoverflow.com/questions/44882363/does-const-iterator-really-need-to-be-a-different-class-than-iterator – user463035818
Was über die Verwendung von 'CustomVector_ref'?Kein const_cast benötigt so –
geza