2016-10-11 2 views
2

Ich verstehe nicht rohe Zeiger ganz gut und leider bin ich nicht erlaubt, <vector> s zu verwenden, so kann ich nicht herausfinden, wie man einen parametrisierten Konstruktor einer Klasse, die ein Array von einer anderen Klasse Objekte als hat seine Eigenschaft.Wie übergebe ich ein dynamisches Array von Objekten an einen parametrisierten Konstruktor einer anderen Klasse?

class A{ 
    ... 
}; 

class B{ 
    int size; 
    A *arr; 
    ... 
    B(int, const A *); // am I declaring this right? 
} 

... 

B::B(int size_, const A *arr_) { // this is the constructor I'm trying to write 
    size = size_; 
    if (arr != nullptr) delete[] arr; 
    arr = new A[size]; 
    memcpy(arr, arr_, sizeof(A) * size); 
} 

Wie kann ich dieses Argument übergeben, ohne den Speicher durcheinander zu bringen? Der obige Code funktioniert nicht richtig, daher möchte ich einige Tipps hören. Ich habe es nicht geschafft, die Lösung zu googlen, obwohl es so aussieht, als wäre meine Frage bereits beantwortet, entschuldige ich mich in diesem Fall.

Ich darf keine sicheren std:: Sachen verwenden. Ich muss herausfinden, wie man es mit der manuellen Speicherzuweisung von C arbeiten lässt. Hoppla, ich meine von C++, danke, dass Sie dies unterstrichen haben.

hier ist also der Konstruktor, die für mich bisher funktioniert:

B::B(int size_, const A *arr_) { 
    size = size_; 
    arr = new A[size_]; 
    for (int i = 0; i < size; i++) arr[i] = arr_[i]; 
} 

Vielen Dank für alle Zeit!

+0

Sie müssen einen vollständigen Testfall bereitstellen. Siehe hier: http://StackOverflow.com/Help/Mcve Es gibt nicht genug Informationen in dem Code, den Sie zur Verfügung gestellt haben, um Ihnen zu sagen, was falsch ist. – xaxxon

+1

können Sie 'std: array' verwenden? –

+1

'if (arr!= nullptr) delete [] arr; 'ist unwahrscheinlich, was Sie in Ihrem Konstruktor wollen. Nun, eigentlich ist es einfach falsch. Und die Verwendung von 'memcpy' ist einfach falsch, es sei denn, Sie wissen, dass' A' trivial kopierbar ist. – jxh

Antwort

3

In Ihrem Konstruktor:

if (arr != nullptr) delete[] arr; 

arr ist ein Klasse-Mitglied, das an dieser Stelle nicht initialisiert wird. Es ist ein Müllzeiger, wahrscheinlich etwas anderes als ein nullptr, und dies wird versuchen, delete der Müllzeiger. Offensichtlich wird das nicht sehr weit gehen.

Einfach entfernen. Ihr Konstruktor setzt size und arr, und das ist alles, was es tun muss. Es gibt keine existierenden Werte von size und arr, um die Sie sich sorgen müssen: Sie bauen ein neues Objekt.

memcpy(arr, arr_, sizeof(A) * size); 

Dies wird nur dann, wenn Ais a POD arbeiten. Verwenden Sie stattdessen std::copy(), die in allen Fällen das Richtige tun. Wenn Sie std::copy() nicht verwenden können und std::vector nicht verwenden dürfen, schreiben Sie eine for-Schleife, um diese Daten manuell zu kopieren.

+1

Bemerkenswert, dass dies immer noch nicht großartig ist, da es standardmäßig A konstruiert und dann kopiert, aber es ist gut genug für die Ebene, die das OP zu sein scheint beim. –

0

Es muss nicht überprüft werden, ob arr im Konstruktor NULL ist, weil arr noch nichts zugewiesen wurde.

memcpy wird nicht zum Kopieren von Klassen verwendet, da Klassen in der Regel Elementfunktionen enthalten, die als Funktionszeiger gespeichert werden. Ihre memcpy-Anweisung sollte nicht verwendet werden, da Funktionszeiger überschrieben werden, die in arr erstellt werden, wenn der neue A [size] -Befehl ausgeführt wird und Klasse B nicht ordnungsgemäß ausgeführt werden kann.

Verwenden Sie eine for-Schleife, um durch arr_ zu iterieren und kopieren Sie nur die Datenelemente von A von arr_ nach arr ist der Weg zu gehen.

Zum Beispiel in der for-Schleife, arr [i] = arr_ [i], wobei i der Index in der for-Schleife ist. Wenn Klasse A keinen überladenen Zuweisungsoperator hat, wird eine flache Kopie der Elementvariablen auftreten. Wenn eine flache Kopie nicht akzeptabel ist, sollte ein überladener Zuweisungsoperator in Klasse A erstellt werden, wenn er nicht existiert.

Verwandte Themen