2016-03-29 1 views
-2

Ich muss eine generische Datenstruktur schreiben, die einem C++ - Vektor als Teil einer Zuweisung ähnelt.So übergeben Sie Daten an eine Vorlagengruppe

Das ist meine Idee für den Vektor:

template<typename T> 
class MyVector { 
private: 
    T* data_; 
    size_t size_; 
public: 
    MyVector(); 
    MyVector(const MyVector &otherVector); 

    // which one should I use? 
    add(const T& value); 
    add(T value); 

    ~MyVector(); 
}; 

Jetzt frage ich mich, wie die Werte auf die Methoden zu übergeben. Aus Java kommend bin ich ein wenig überfordert. In Java würden Sie nicht zögern und den Wert als Referenz übergeben, der GC würde das Objekt niemals löschen, wenn es noch referenziert wird.

in C++ Sie ein Chaos verursachen würde, wenn Sie durch Bezugnahme Berücksichtigung Code wie folgt passieren würde:

void myFunction(MyVector &myVector) { 
    int a = 5; 

    myVector.add(a); 
} 

int main() { 

    auto vector = MyVector<int>(); 

    myFunction(vector); 

    // now the vector contains a reference to 
    // something that doesn't exist anymore. 
} 

Wie lösen Sie dieses Problem? Würden Sie nur durch Referenz übergeben und eine Kopie erstellen oder übergeben Sie nach Wert (was eine Kopie für Sie erstellt)

Mit Blick auf die C++ - Schnittstelle std :: vector sehe ich, dass sie Referenzen verwenden.

Ich sehe nicht den Wert der Weitergabe als Referenz, wenn Sie Ihre eigene Kopie erstellen müssen.

+0

Wenn Sie nach unten Abstimmung in dieser Frage könnten Sie bitte einen Grund nennen? – TimKaechele

+0

Ich vermute, Sie haben keine genaue Vorstellung von der Bedeutung von "ein Objekt durch Verweis übergeben" in C++. Es ist falsch, dass "durch Verweis gehen und eine Kopie erstellen"; Durch Verweis übergeben, ist es der C++ - Weg, um eine Kopie zu vermeiden. Ich empfehle Ihnen, diese Antwort sorgfältig zu lesen: http://stackoverflow.com/a/5922217/6022656 – max66

Antwort

1

add(const T& value) ist in Ordnung, Sie sollten nur sicher sein, dass es richtig zugewiesen Operator für T definiert ist. Also, die Implementierung wird:

void Add(const T& value) { 
    if (m_size == m_maxSize) realloc(); // stuff to have enough space 
    m_data[m_size++] = value; // here copy is creating 
} 

Standard Impl des Zuweisungsoperators nur Byte-Kopie Felder der Klasse, es ist nicht immer korrekt.

Andere Lösung, wenn Sie mehr Java-Stil semantischen wollen, ist T = shared_ptr<YourType> oder T = YourType* Letztere zu machen ist ziemlich schwierig, weil Geschick der manuellen Kontrolle der Lebensdauer erforderlich ist, so ist nicht wünschenswert, C++ Anfänger.

void myFunction(MyVector<shared_ptr<X>> & myVector) 
{ 
    shared_ptr<X> x(new X(...)); 
    myVector.add(x); 
} 

funktioniert ähnlich wie Referenzen in Java. Andere Art und Weise, die in alten Zeiten verwendet wurden:

template<typename T> 
class MyVector { 
private: 
    T** data_; // now you have array of pointers, so should be careful 
.... 
    add(T* value); 
.... 
} 

void myFunction(MyVector<X> & myVector) 
{ 
    X * x = new X(...); 
    myVector.add(x); // now x belongs to myVector and it should handle its lifetime 
} 
+0

Vielen Dank, das hat mein Problem gelöst. – TimKaechele