Несколько экземпляров класса, содержащего статические массивы разных размеров - PullRequest
0 голосов
/ 30 сентября 2019

Мне нужно иметь несколько экземпляров класса. Каждый экземпляр должен содержать массив предварительно определенного размера. Размеры массивов постоянны и доступны во время компиляции, поэтому я хочу распределить их статически.

Мне нужно собрать экземпляры в один «объект-массив», чтобы я мог получить к ним доступ, используя итератор,Мои проблемы:

  1. Статическое распределение с использованием аргумента конструктора не работает.
  2. Создание объектов в цикле не работает.

Вот пример кода того, что я хочу сделать:

//Class definition of buffer
class mybuffertype{    
    public:
        mybuffertype(int size);
        int bufsize;
        float *buffer;    
};

//Constructor of buffer
mybuffertype::mybuffertype(int size){
    bufsize=size;
    buffer=new float[bufsize];      //Dynamic allocation
    //float buffer[bufsize];        //This static allocation doesn't work
}

//Class definition of container
class container{    
    public:
        container();
        static const int n_buffers=3;
        const int n_sizes[n_buffers]={4,5,6};
        mybuffertype mybuffers[n_buffers];     
};

//Constructor of container
container::container(void){      
    int i;
    for(i=0;i<n_buffers;i++){
        mybuffertype mybuffers[i]= mybuffertype(n_sizes[i]);
    }      
}

//Main
int main(void){    
    container obj;    
    int i;
    for(i=0;i<obj.n_buffers;i++){
        printf("Size: %d \t 1st element: %f\n",
              obj.mybuffers[i].size,
              obj.mybuffers[i].buffer[0]);
    }
}

Что лучшеспособ сделать это?

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

Из списка размеров во время компиляции вы можете создать коллекцию буферов (неоднородного размера).

template <size_t... Sizes>
class Container
{
    std::tuple<std::array<double, Sizes>...> buffers;
public:
    template<size_t I>
    gsl::span<double> get() { return std::get<I>(buffers); }
    // etc.
};

Немного сложнее получить доступ к буферу по индексу времени выполнения. Если вы не хотите включать размер с указателем данных, переключите gsl::span<double> для double*.

template <size_t... Sizes>
class Container
{
    std::tuple<std::array<double, Sizes>...> buffers;
    std::array<gsl::span<double>, sizeof...(Sizes)> lookup;

    template <size_t... Idxs>
    array<gsl::span<double>, sizeof...(Sizes)> make_lookup(std::index_sequence<Idxs...>)
    {
        return { get<Idxs>(buffers)... };
    }

public:
    Container() : lookup(make_lookup(std::index_sequence_for<Sizes...>{})) {}

    template<size_t I>
    gsl::span<double> get() { return std::get<I>(buffers); }

    gsl::span<double> operator[](size_t i) { return lookup[i]; }
    // etc.
};
0 голосов
/ 30 сентября 2019

Вы смешиваете статическую концепцию с реализацией. Вы не можете создать экземпляр статического массива или класса в конструкторе.

Вы можете сделать что-то вроде этого:


#include <cstdio>
using namespace std;

//Class definition of buffer
class mybuffertype{    
public:
    mybuffertype(int size) {
      bufsize=size;
      buffer=new float[bufsize];      //Dynamic allocation
    }
    virtual ~mybuffertype() {
      delete buffer;
    }
    int bufsize;
    float *buffer;
};

class StaticData {
public:
    StaticData(int n_buffers): n_buffers(n_buffers) {
      mybuffers = new mybuffertype*[n_buffers];
      for (int i = 0; i < n_buffers; ++i)
        mybuffers[i] = new mybuffertype(3+i);
    }
    virtual ~StaticData() {
      for (int i = 0; i < n_buffers; ++i)
        delete mybuffers[i];
      delete [] mybuffers;
    }
    const int n_buffers;
    mybuffertype **mybuffers;
};

//Class definition of container
class MyContainer{
public:
    static StaticData buffers;
};
StaticData MyContainer::buffers(3);

//Main
int main(int argc, char ** argv){    
    for(int i = 0; i < MyContainer::buffers.n_buffers; i++){
        printf("Size: %d \t 1st element: %f\n",
               MyContainer::buffers.mybuffers[i]->bufsize,
               MyContainer::buffers.mybuffers[i]->buffer[0]);
    }
    return 0;
}

Все статические буферы находятся в новом классе StaticData, который вызовет конструктор только один раз, так как он объявлен статическим в MyContainer. StaticData также использует инициализацию массива C ++ 11 для классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...