2014-10-04 19 views
5

Mam klasy, która musi przechowywać tablicę o zmiennej wielkości. Idealnie, rozmiar ten byłby zdefiniowany jako parametr nadany konstruktorowi klasy.Jak zainicjować tablicę o zmiennych rozmiarach w klasie C++?

mogę określić stałą, a następnie pracować z tym, co widać poniżej:

#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; 
    } 
} 

jednak chciałbym to zrobić tak:

#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; 
    } 
} 

Kompilator naprawdę robi” Jednak podoba mi się moje podejście, więc szukam alternatywnego sposobu robienia rzeczy.

Zrobiłem trochę googlowania na ten temat, ale moje poszukiwania nie przyniosły rezultatu. Znalazłem podejście this, które robi to za pomocą dynamicznego przydzielania pamięci. Jest to coś, czego chciałbym uniknąć, więc szukam rozwiązania, które nie polega na tym. Może być (i zaczynam myśleć), że jest to jedyne eleganckie rozwiązanie mojego problemu (a jeśli tak jest, pytanie powinno oczywiście zostać zamknięte jako duplikat).

+6

Użyj ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector). –

+0

Nie jestem wielkim fanem tablic w ogóle, do większości celów.O ile naprawdę ich nie potrzebujesz, aby uzyskać jakąś postrzeganą optymalizację, 'std :: vector' jest twoim przyjacielem, a bardziej prawdopodobne, że ugnie się wraz z twoimi wymaganiami. Ale możesz użyć [std :: array] (http://en.cppreference.com/w/cpp/container/array) ... wygodnej alternatywie C++ do C tablic. – HostileFork

+6

@HostileFork: 'Std :: array' nie jest zmiennym rozmiarem. 'std :: unique_ptr ' jest komponentem standardowym dla tablicy z ustawionym rozmiarem na budowie. 'std :: vector ' dla tablicy, której rozmiar może się zmieniać podczas jej trwania. –

Odpowiedz

9

Wymagane jest użycie alokacji dynamicznej, ponieważ sizeof (Classy) musi być stałą czasu kompilacji. Nie ma możliwości zwiększenia wewnętrznego rozmiaru obiektu. Ale alokacja dynamiczna nie musi być tak skomplikowana, jak sugeruje to łącze.

Można to zrobić tak:

#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; 
    } 
} 

Pozwoli wielkość zmieniać w momencie stworzenia, a być ustalona później. std::unique_ptr zajmie się automatycznym niszczeniem zawartości tablicy, gdy twój obiekt umiera.

1

chcesz używać szablonów, aby rozwiązać ten problem:

#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; 
}; 

Następnie można użyć swoją klasę tak:

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

mogli Państwo bardzo dobrze opt nie używać std :: tablicę, preferuje tablicę w stylu c. Ale piszemy w C++, więc używajmy lepszych narzędzi językowych, które mamy do dyspozycji :)

+3

To nie pozwala "przekazać rozmiaru do konstruktora", ponieważ wymaga tego pytanie. –

2

Należy dynamicznie przydzielić tablicy przy użyciu new[], a następnie delete[] go w destruktora. Alternatywnie, należy użyć wartości std::vector<int> i reserve, która została przekazana do konstruktora. Jeszcze jedna metoda polega na tym, aby twoja klasa była szablonowana, przyjmując argument za ilością elementów, które chcesz mieć, ale to całkowicie usuwa jej aspekt dynamiczny (i równie dobrze możesz używać std::array w tym punkcie.

wiem chcesz uniknąć dynamicznej alokacji, ale jest to najbardziej skuteczny sposób, aby robić to, co chcesz (bo vector może zająć więcej miejsca niż można się spodziewać).

3

Cóż, myślę, że nie można zrobić bez użycia dynamicznej alokacji pamięci przy użyciu klasycznej tablicy, ale możesz użyć std :: vector. Możesz to zrobić tak:

#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' potrzebuje typu –

+0

tak, oczywiście, zapomniałem go napisać: D dzięki, zaktualizowałem to. –

+0

Dlaczego śledzisz rozmiar 'std :: vector' z' int arraysize; '? Nie możesz po prostu użyć metody 'size()' wektora? – Galik

Powiązane problemy