2014-10-04 7 views
5

Ich habe eine Klasse, die ein Array mit variabler Größe speichern muss. Idealerweise wird diese Größe als ein Parameter definiert, der dem Konstruktor der Klasse übergeben wird.Wie initialisiere ich ein Array variabler Größe in einer C++ - Klasse?

Ich kann eine Konstante definieren und dann mit dem arbeiten, wie unten zu sehen:

#include <iostream> 
#define ARRSIZE 5 

class Classy{ 
    private: 
     int myarray[ARRSIZE]; 

    public: 
     Classy(); 
     void printarray(); 
}; 

Classy::Classy(){ 
    for(int i = 0; i < ARRSIZE; i++){ 
     myarray[i] = i * i * 2; 
    } 
} 

void Classy::printarray(){ 
    for(int i = 0; i < ARRSIZE; i++){ 
     std::cout << myarray[i] << std::endl; 
    } 
} 

aber ich mag es, wie dies zu tun:

#include <iostream> 
class Classy{ 
    private: 
     int arraysize; 
     int myarray[arraysize]; 

    public: 
     Classy(int parraysize); 
     void printarray(); 
}; 

Classy::Classy(int parraysize){ 
    arraysize = parraysize; 
    for(int i = 0; i < arraysize; i++){ 
     myarray[i] = i * i * 2; 
    } 
} 

void Classy::printarray(){ 
    for(int i = 0; i < arraysize; i++){ 
     std::cout << myarray[i] << std::endl; 
    } 
} 

Der Compiler wirklich doesn‘ Aber ich mag meine Herangehensweise, also suche ich nach einer alternativen Art, Dinge zu tun.

Ich habe etwas über das Thema gegooglet, aber meine Suche ergab sich nicht fruchtbar. Ich fand this Ansatz, der es dynamische Speicherzuweisung verwendet. Dies möchte ich vermeiden, deshalb suche ich nach einer Lösung, die nicht darauf angewiesen ist. Es kann gut sein (und ich fange an zu denken), dass es die einzige elegante Lösung für mein Problem ist (und wenn das der Fall ist, sollte die Frage natürlich als Duplikat geschlossen werden).

+6

Verwenden Sie ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector). –

+0

Ich bin kein großer Fan von Arrays im Allgemeinen, für die meisten Zwecke.Wenn du sie nicht wirklich für eine wahrgenommene Optimierung brauchst, ist 'std :: vector' dein Freund und neigt eher dazu, deine Anforderungen zu erfüllen. Aber Sie könnten [std :: array] (http://en.cppreference.com/w/cpp/container/array) ... die bequeme C++ - Alternative zu C-Arrays verwenden. – HostileFork

+6

@HostileFork: Ein 'std :: array' hat keine variable Größe. 'std :: unique_ptr ' ist die Standardkomponente für ein Array, dessen Größe bei der Konstruktion festgelegt wurde. 'std :: vector ' für ein Array, dessen Größe während seiner Lebensdauer variieren kann. –

Antwort

9

Die dynamische Zuweisung ist erforderlich, da sizeof (Classy) eine Kompilierzeitkonstante sein muss. Es gibt keine Möglichkeit für die interne Größe Ihres Objekts zu wachsen. Die dynamische Zuordnung muss jedoch nicht so kompliziert sein, wie diese Verknüpfung vermuten lässt.

Sie können es wie folgt tun:

#include <memory> 
class Classy 
{ 
    private: 
     int arraysize; 
     std::unique_ptr<int[]> myarray; 

    public: 
     Classy(int parraysize); 
     void printarray(); 
}; 

Classy::Classy(int parraysize) 
    : arraysize{parraysize} 
    , myarray{new int[arraysize]} 
{ 
    for(int i = 0; i < arraysize; i++){ 
     myarray[i] = i * i * 2; 
    } 
} 

#include <iostream> 
void Classy::printarray() 
{ 
    for(int i = 0; i < arraysize; i++){ 
     std::cout << myarray[i] << std::endl; 
    } 
} 

Dies wird die Größe erlauben im Moment der Schöpfung zu variieren, und danach fixiert werden. std::unique_ptr kümmert sich um die automatische Zerstörung der Array-Inhalte, wenn Ihr Objekt stirbt.

1

Sie wollen Vorlagen verwenden, um dieses Problem zu lösen:

#include <array> 

template<std::size_t ArraySize> 
class Classy final 
{ 
public: 
    static const std::size_t size = ArraySize; 

    /* The rest of your public interface here */ 
private: 
    std::array<int, ArraySize> m_array; 
}; 

Dann können Sie Ihre Klasse wie folgt verwenden:

int main() 
{ 
    Classy<5> hasArrayOfFiveElements; 
    return 0; 
} 

Sie könnten sehr gut opt ​​nicht std :: Array verwenden, bevorzugt für ein c-artiges Array. Aber wir schreiben C++, also nutzen wir die besseren Sprachmöglichkeiten, die uns zur Verfügung stehen :)

+3

Dadurch können Sie nicht "die Größe an den Konstruktor übergeben", wie die Frage erfordert. –

2

Sie müssen Ihr Array dynamisch mit new[] und dann delete[] in Ihrem Destruktor zuweisen. Alternativ verwenden Sie std::vector<int> und reserve die Menge an den Konstruktor übergeben. Noch eine Methode besteht darin, Ihre Klasse zu templatieren, indem Sie ein size_t Argument für die Menge der Elemente verwenden, die Sie haben möchten, aber das den dynamischen Aspekt davon vollständig entfernt (und Sie könnten 10 zu diesem Zeitpunkt auch verwenden.

ich weiß, dass Sie die dynamische Zuordnung vermeiden möchten, aber es ist der effizienteste Weg, zu tun, was Sie wollen (weil vector könnte mehr Platz in Anspruch nehmen, als Sie erwarten).

3

Nun, ich glaube, Sie nicht tun können, Wenn Sie ein klassisches Array verwenden, verwenden Sie keine dynamische Speicherzuweisung, aber Sie können std :: vector verwenden, und zwar folgendermaßen:

#include <iostream> 
class Classy{ 
    private: 
     int arraysize; 
     std::vector<int> myArrayOfInts; 

    public: 
     Classy(int parraysize); 
     void printarray(); 
}; 

Classy::Classy(int parraysize){ 
    arraysize = parraysize; 
    for(int i = 0; i < arraysize; i++){ 
     myArrayOfInts.push_back(i * i * 2); 
    } 
} 

void Classy::printarray(){ 
    for(int i = 0; i < myArrayOfInts.size(); i++){ //you could also use arraysize, but then you 
     std::cout << myArrayOfInts[i] << std::endl;//must update it when you add or remove any 
    }            // element from vector 
} 
+0

'std :: vector' braucht einen Typ –

+0

ja, natürlich habe ich vergessen, es zu schreiben: D danke, ich habe es aktualisiert. –

+0

Warum verfolgen Sie die Größe des 'std :: vector' mit' int arraysize; '? Kannst du nicht einfach die 'size()' Methode des Vektors benutzen? – Galik

Verwandte Themen