Určete velikost pole v konstruktoru inicializátor

hlasů
13

V kódu níže bych nakupení být definován jako pole o velikosti x, je-li třída konstruktor volal. Jak to mohu udělat?

class Class
{
public:
  int array[];
  Class(int x) : ??? { }
}
Položena 15/04/2009 v 15:08
zdroj uživatelem
V jiných jazycích...                            


11 odpovědí

hlasů
27

Vy lidé jste tak složitá to. Samozřejmě, můžete to udělat v C ++. To je v pořádku pro něj použít normální pole pro efektivitu. Vektor má smysl pouze v případě, že neví konečnou velikost pole dopředu, tedy potřebuje růst v průběhu času.

Pokud můžete znát velikost pole o jednu úroveň výše v řetězci, je templated třída je nejjednodušší, protože není dynamická alokace a není šance, že úniky paměti:

template < int ARRAY_LEN > // you can even set to a default value here of C++'11

class MyClass
  {   
  int array[ARRAY_LEN]; // Don't need to alloc or dealloc in structure!  Works like you imagine!   
  }

// Then you set the length of each object where you declare the object, e.g.

MyClass<1024> instance; // But only works for constant values, i.e. known to compiler

Pokud nemůžete znát délku na místě deklarovat objekt, nebo chcete-li znovu použít stejný objekt s různými délkami, nebo je nutné přijmout neznámé délky, pak je třeba přidělit ji v konstruktoru a zdarma ji váš destructor ... (a teoreticky vždy zkontrolujte, zda to fungovalo ...)

class MyClass
  {
  int *array;

  MyClass(int len) { array = calloc(sizeof(int), len); assert(array); }   
  ~MyClass() { free(array); array = NULL; } // DON'T FORGET TO FREE UP SPACE!
  }
Odpovězeno 04/09/2012 v 22:19
zdroj uživatelem

hlasů
17

Nelze inicializovat velikosti pole s non-const dimenzi, která nemůže být vypočtené v době kompilace (alespoň ne v aktuální C ++ standardu, pokud vím).

I doporučujeme používat std::vector<int>namísto pole. Poskytuje celou řadu jako syntaxe pro většinu operací.

Odpovězeno 15/04/2009 v 15:11
zdroj uživatelem

hlasů
11

Používat nový operátor:

class Class
{
   int* array;
   Class(int x) : array(new int[x]) {};
};
Odpovězeno 15/04/2009 v 15:13
zdroj uživatelem

hlasů
4

Copak nechápeš, že není nutné použít vektor, pokud někdo chce využít pole Je to otázka efektivity, například menší prostor, čas kopírování (v takovém případě, pokud je správně, že není ani nutné odstranit pole v jiném destructor), atd. wichever důvody, jeden má.

Správná odpověď je: (citováno)

class Class
{
   int* array;
   Class(int x) : array(new int[x]) {};
};

Nesnažte se nutit jednu používat non optimálních alternativ nebo budete matoucí nezkušené programátory

Odpovězeno 06/12/2010 v 08:05
zdroj uživatelem

hlasů
3

Omlouvám se za necroing této staré vlákno. Tam je vlastně způsob, jak zjistit velikost pole kompilaci. Jde to nějak takhle:

#include <cstdlib>

template<typename T>
    class Class
    {
        T* _Buffer;

        public:
        template<size_t SIZE>
            Class(T (&static_array)[SIZE])
            {
                _Buffer = (T*)malloc(sizeof(T) * SIZE);

                memcpy(_Buffer, static_array, sizeof(T) * SIZE);
            }

            ~Class()
            {
                if(_Buffer)
                {
                    free(_Buffer);
                    _Buffer = NULL;
                }
            }
    };

int main()
{
    int int_array[32];
    Class<int> c = Class<int>(int_array);

    return 0;
}

Případně, pokud nerad malloc / nové, pak si můžete vytvořit velikost templated třídu místo. I když, já bych opravdu doporučuji a syntax je docela ošklivý.

#include <cstdio>

template<typename T, size_t SIZE>
    class Class
    {
        private:
            T _Array[sz];
        public:
            Class(T (&static_array)[SIZE])
            {
                memcpy(_Array, static_array, sizeof(T) * SIZE);
            }
    };

int main()
{
    char int_array[32];
    Class<char, sizeof(int_array)> c = Class<char, sizeof(int_array)>(int_array);
    return 0;
}

Tak jako tak, doufám, že to bylo užitečné :)

Odpovězeno 06/01/2011 v 11:09
zdroj uživatelem

hlasů
3

Nemyslím si, že se to dá udělat. Alespoň ne tak, jak si přejete. Nelze vytvořit staticky velikosti pole (array []), když je velikost pochází z dynamických informací (x).

Budete muset buď uložit ukazatel-to-int a velikost, a přetížení copy konstruktor, operátor přiřazení a destruktor s ní zacházet, nebo použít std :: vector.

class Class
{
  ::std::vector<int> array;
  Class(int x) : array(x) { }
};
Odpovězeno 15/04/2009 v 15:16
zdroj uživatelem

hlasů
1

Namísto použití přímého pole, proč nepoužít místo vektoru.

class SomeType {
  vector<int> v;
  SomeType(size_t x): v(x) {}
};

Použitím vektoru vám automatickou ochranou proti úniku tváří v tvář výjimky a mnoho dalších výhod oproti syrové pole.

Odpovězeno 15/04/2009 v 15:13
zdroj uživatelem

hlasů
0

Měl jsem stejný problém a já jsem vyřešil to takhle

class example
{
  int *array;

  example (int size)
  {
    array = new int[size];
  }
}
Odpovězeno 13/10/2018 v 05:47
zdroj uživatelem

hlasů
0

Dvě možnosti:

Použít std :: vector. To umožňuje snadnou úpravou velikosti matice.
Použijte std :: tr1 :: pole. To má statickou velikost.

Obojí může být správně inicializována v seznamu konstruktéři Inicializátor.

Odpovězeno 15/04/2009 v 16:53
zdroj uživatelem

hlasů
0

Deklarovat své pole jako ukazatel. Můžete jej inicializovat v seznamu Inicializátor později průchozími nové.

Lepší použít vektor pro neznámé velikosti.

Možná budete chtít podívat na tuto otázku stejně jako na proměnlivou délku pole.

Odpovězeno 15/04/2009 v 15:15
zdroj uživatelem

hlasů
0

Můžete to udělat v C ++ - použít std :: vector namísto:

#include <vector>

struct A {
   std::vector <int> vec; 
   A( int size ) : vec( size ) {
   }
};
Odpovězeno 15/04/2009 v 15:13
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more