2017-04-25 2 views
1

Ich versuche, einen gemeinsamen Zeiger auf eine feste Größe Array in einem Vektor zu speichern, ich möchte einen gemeinsamen Zeiger verwenden, weil ich einen Zeiger auf das Array an eine andere Klasse weitergeben muss schreibe in das Array, und ich möchte mehr als ein Array haben, weil ich mehr Instanzen der Schreibklasse haben kann und jeder ein Array benötigt, um zu schreiben, sie werden eine Menge Daten in die Arrays schreiben, so dass sie nicht bewegt werden gute Wahl.Gemeinsame Zeiger auf Array in Vektor speichern

std::shared_ptr<char> sp(new char [MAX_LENGTH], std::default_delete<char[]>()); 
arrayVect.push_back(sp); 

der Vektor wird als Klassenmitglied definiert wie:

std::vector< std::shared_ptr< char [ MAX_LENGTH ] > > arrayVect; 

ich den Fehler bekommen:

error: no matching function for call to ‘std::vector<std::shared_ptr<char [MAX_LENGTH]> >::push_back(std::shared_ptr<char []>&)’ 

ich verschiedene Alternativen ausprobiert, aber keiner von ihnen gearbeitet haben, könnten Sie weisen auf die richtige Vorgehensweise hin? oder gibt es eine alternative, die mir fehlt? Die Schreibklasse benötigt ein Array von Zeichen für die Schreibfunktion, also denke ich, dass ich mit dem Array fest bin.

danke!

+2

'std :: vector > arrayVect;' – CinCout

+1

Whould dass kein Vektor der gemeinsamen Zeiger auf ein einzelnes Zeichen sein? Was passiert, wenn ich etwas wie: * (arrayVect.at (0)) [1] oder etwas ähnliches zugreifen möchte? –

+0

Nein, das ist kein Zeiger auf ein einzelnes Zeichen. Eigentlich zerfällt Array im Allgemeinen zu Zeigern. –

Antwort

2

Ich fühle mich wie Shared Ownership ist das falsche Modell hier. Konzeptionell, warum möchten Sie, dass Ihre Mitarbeiter weiterhin an einem Array arbeiten, wenn niemand das Ergebnis mehr beobachtet?

So würde ich die arrayVect besitze die Arrays und Zeiger auf die Arrays an die Arbeiter verteilen. Wenn es nicht sinnvoll ist, eines der Arrays beizubehalten, halten Sie zuerst den Arbeiter an und löschen Sie dann das Array.

Der einfachste Weg, um dieses Verhalten zu erhalten, ist arrayVect ein std::vector<std::unique_ptr<std::array<char, MAX_LENGTH>>> machen. Dann kann der Zeiger auf das zugrunde liegende char[MAX_LENGTH]-Array, das Sie an einen Mitarbeiter übergeben können, abgerufen werden, indem Sie arrayVect[idx].get().data() aufrufen.

Durch die zusätzliche Indirektion durch die unique_ptr bleiben die Zeiger auf die Arrays gültig, auch wenn der Vektor in der Größe geändert wird.

EDIT: Hier ist ein Beispiel, wie das mit unique_ptr arbeiten kann s auch wenn Ihre Mitarbeiter benötigen auch einen Zeiger auf das Array:

class Worker { 
public: 
    Worker(std::array<char, MAX_SIZE>* array) 
     : _array{array} { 
    } 

    void perform_work() { 
     function_that_requires_c_arrays(_array->data()); // maybe also a size parameter? 
    } 

private:  
    std::array<char, MAX_SIZE>* _array; 
}; 

int main() { 
    std::vector<std::unique_ptr<std::array<char, MAX_SIZE>>> arrayVect; 
    arrayVect.emplace_back(std::make_unique<std::array<char, MAX_SIZE>>())); 

    Worker w{arrayVect.back().get()}; 
    w.perform_work(); 
} 
+0

ist make_unique C++ 14? Ich habe nur C++ 11 :( –

+0

@ JD.gg Ja ist es, alternativ können Sie einfach 'arrayVect.emplace_back (neue std :: array {});'. – Corristo

+0

Danke! Es funktioniert Jetzt macht die Idee von usin unique_ptr auch mehr Sinn als shared_ptr. –

1

Try-Vektor erklärt wie unten,

std::vector<std::shared_ptr<char> > arrayVect;

Eigentlich erklären Sie falsch Vektor. Bitte versuchen Sie es mit der obigen Änderung zu überprüfen. Ich hoffe es hilft!

1

Sie std::vector<std::shared_ptr<char>> ohne Array-Notation verwenden können. Es ist wichtig, dass Sie dann immer noch std::default_delete<char[]>() als Deleter verwenden. Hier ist ein komplettes Beispiel.

#include <iostream> 
#include <vector> 
#include <memory> 

#define MAX_LENGTH 10 

int main() { 
    std::vector<std::shared_ptr<char>> arrayVect; 
    std::shared_ptr<char> sp(new char[MAX_LENGTH], std::default_delete<char[]>()); 
    arrayVect.push_back(sp); 
    arrayVect.push_back(std::shared_ptr<char>(new char[MAX_LENGTH], std::default_delete<char[]>())); 

    char q = 0; 
    for (size_t x = 0; x < arrayVect.size(); ++x) 
     for (size_t y = 0; y < MAX_LENGTH; ++y) 
      arrayVect.at(x).get()[y] = ++q; 

    for (size_t x = 0; x < arrayVect.size(); ++x) 
     for (size_t y = 0; y < MAX_LENGTH; ++y) 
      std::cout << int(arrayVect.at(x).get()[y]) << '\n'; // Int cast to print numbers, and not ASCII control characters 
} 
Verwandte Themen