Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
#1

Большой константный массив - C++

23.03.2016, 22:17. Просмотров 517. Ответов 13
Метки нет (Все метки)

Нужно хранить в классе большой константный массив (вектор). Модификатор const не обязателен (хотя было бы неплохо), имеется ввиду что массив меняться не будет, он всегда постоянный - постоянная длина, постоянные значения. Ручками вбить не получится - значений слишком много. Обращение к нему будет только внутри класса. Сделал так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//A.h
 
class A
{
    public
        A();
    private:
        static vector<double> x;
}
 
 
 
//A.cpp
 
#include "A.h"
 
vector<double> A::x;
 
A::A()
{
    if (x.size() == 0)
    {
        x.resize(1024);
        for (int i = 0; i < 1024; ++i)
            x[i] = i;
    }
}
1) Это вообще нормально? Так делают? Если нет, то как делают? По-моему это как то не по-людски - массив вроде бы заранее известен, но все равно тратим время на его создание во время исполнения... А если бы элементов было гораздо больше и формировались бы сложнее...
2) Очень тяжело сделать чтобы он заполнялся во время компиляции?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт CЭксперт С++
12891 / 7277 / 811
Регистрация: 27.09.2012
Сообщений: 17,976
Записей в блоге: 2
Завершенные тесты: 1
23.03.2016, 22:29     Большой константный массив #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
#include <algorithm>
 
std::vector<int> getGreaterVector(int first, int last)
{
    if(last<first)
        std::swap(first, last);
    std::vector<int> result(last-first);
    std::iota(result.begin(), result.end(), first);
    return result;
}
 
 
int main()
{
    std::vector<int> vec = getGreaterVector(0, 1024) ;
    for(auto e: vec)
        std::cout << e << ' ';
}
http://rextester.com/KMK32815

Цитата Сообщение от pav1uxa Посмотреть сообщение
Очень тяжело сделать чтобы он заполнялся во время компиляции?
vector - динамическая память, так что рантайм.
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
23.03.2016, 22:37  [ТС]     Большой константный массив #3
Croessmah, мне не нужна функция заполнения массива. Я знаю что он у меня всегда будет одинаковых размеров и иметь одинаковые значения. И должен являться приватным членом класса.

Просто никогда еще такого не приходилось делать, и мой код кажется мне каким-то стремным. Поэтому и спрашиваю, нормально ли это.

Цитата Сообщение от Croessmah Посмотреть сообщение
vector - динамическая память, так что рантайм.
Точно, что то стормозил...
Croessmah
Модератор
Эксперт CЭксперт С++
12891 / 7277 / 811
Регистрация: 27.09.2012
Сообщений: 17,976
Записей в блоге: 2
Завершенные тесты: 1
23.03.2016, 22:47     Большой константный массив #4
Цитата Сообщение от pav1uxa Посмотреть сообщение
Я знаю что он у меня всегда будет одинаковых размеров и иметь одинаковые значения.
Значит его нужно инициализировать один раз - при старте приложения.
Зачем в конструкторе каждый раз дергать его размер?
Делаете, например, функцию, которая инициализирует нужный вектор и возвращает его.
В силу применения RVO/NRVO, copy-elision,
ну или на крайняк перемещающего конструктора,
не будет даже копирования элементов между векторами.
C++
1
vector<double> A::x = get_my_vector(/*...*/) ;//A::x инициализирован при старте программы
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
23.03.2016, 22:56  [ТС]     Большой константный массив #5
Цитата Сообщение от Croessmah Посмотреть сообщение
Значит его нужно инициализировать один раз - при старте приложения.
Вот в этом и вопрос - как это у людей делается. Так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//A.h
 
class A
{
    public
        A();
    private:
        static vector<double> x;
}
 
 
//A.cpp
 
#include "A.h"
 
vector<double> initx()
{
    vector<double> x(1024);
    for (int i = 0; i < 1024; ++i)
            x[i] = i;
    return x;
}
 
vector<double> A::x = initx();
 
A::A()
{
}
hoggy
6168 / 2534 / 444
Регистрация: 15.11.2014
Сообщений: 5,612
Завершенные тесты: 1
25.03.2016, 21:22     Большой константный массив #6
Цитата Сообщение от pav1uxa Посмотреть сообщение
как это у людей делается.
статическая информация подгружается как есть,
при старте приложения:

C++
1
int arr[] = {  #include "values" };
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
26.03.2016, 09:25  [ТС]     Большой константный массив #7
Цитата Сообщение от hoggy Посмотреть сообщение
int arr[] = { *#include "values" };
1. Мне нужен именно вектор, как я написал выше уже 2 раза.
2. Тысячу значений забивать в ручную не очень то хочется.

Не по теме:

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

Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
26.03.2016, 10:07     Большой константный массив #8
Цитата Сообщение от pav1uxa Посмотреть сообщение
Не по теме:
Просто есть сторонняя библиотека, которую редактировать не очень хотелось бы. Из нее я использую метод, в который нужно передавать с определенной периодичностью вектор. В моем конкретном случае он будет постоянный, вот и спрашиваю как его правильней инициализировать.
Все просто до ужаса: переписываешь вектор (или если по быстрому то порождаешь класс от std::vector, а если как в stl задумано даешь ему другой аллокатор, который всегда возвращает одни и тот же адрес памяти, при этом сам вектор делаешь статического размера) с учетом возможности дать ему указатель на данные извне. Делаешь статик массив в классе. В конструкторе даешь ему указатель на этот массив. При этом вектор должен иметь флаг отключающий удаление массива. Если поплясать с бубном то по значению указателя можно определить куда он смотрит - в сегмент данных или в кучу.
Цитата Сообщение от pav1uxa Посмотреть сообщение
Тысячу значений забивать в ручную не очень то хочется.
Ну можно этот константный массивчик сгенерить другой прогой, вывести так чтобы он был валидным кодом и подключить где нужно. Ну а сейчас вроде для таких дел constexpr появился.
SatanaXIII
Супер-модератор
Эксперт С++
5589 / 2623 / 239
Регистрация: 01.11.2011
Сообщений: 6,448
Завершенные тесты: 1
28.03.2016, 15:51     Большой константный массив #9
pav1uxa, из файла загрузить можно.

Можно вообще сгенерировать программно один раз заголовочный файл вида:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef MyVectorH
#define MyVectorH
 
#include <vector.h>
 
class MyVector
{
  public: std::vector<int> v;
 
  MyVector()
  {
    v.push_back(1); // Вот это
    v.push_back(2); //  собственно
    v.push_back(3); //  и генерировать
  }
};
 
extern MyVector v;
 
#endif
И использовать его:
C++
1
2
3
4
5
6
7
8
9
#include "MyVector.h"
 
{
  MyVector mv;
  for( int i=0; i<mv.v.size(); i++ )
  {
    Use(mv.v[i]);
  }
}
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
28.03.2016, 18:16  [ТС]     Большой константный массив #10
Цитата Сообщение от SatanaXIII Посмотреть сообщение
C++
1
2
3
v.push_back(1); // Вот это
v.push_back(2); // *собственно
v.push_back(3); // *и генерировать
А в чем отличие такого подхода от
C++
1
2
3
    vector<double> x(1024);
    for (int i = 0; i < 1024; ++i)
        x[i] = i;
SatanaXIII
Супер-модератор
Эксперт С++
5589 / 2623 / 239
Регистрация: 01.11.2011
Сообщений: 6,448
Завершенные тесты: 1
29.03.2016, 13:38     Большой константный массив #11
pav1uxa, генерировать извне удобнее, не более.
olper
24 / 24 / 11
Регистрация: 02.12.2013
Сообщений: 75
04.04.2016, 19:34     Большой константный массив #12
Цитата Сообщение от Croessmah Посмотреть сообщение
Значит его нужно инициализировать один раз - при старте приложения.
Цитата Сообщение от pav1uxa Посмотреть сообщение
Вот в этом и вопрос - как это делается.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//A.h
 
class A
{
    public
        A()
        {    
             if (x.size() == 0)
             {
                  x.resize(1024);
                  for (int i = 0; i < 1024; ++i)
                  x[i] = i;
             }
        }
    private:
        vector<double> x;
} 
//A.cpp
 
#include "A.h"
 
A a; // конструктор выполняется до main
Добавлено через 6 минут
Цитата Сообщение от pav1uxa Посмотреть сообщение
Очень тяжело сделать чтобы он заполнялся во время компиляции?
Цитата Сообщение от pav1uxa Посмотреть сообщение
если бы элементов было гораздо больше и формировались бы сложнее
препроцессор сбежит от вас за такие мечты )
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
04.04.2016, 20:04  [ТС]     Большой константный массив #13
olper, Вы невнимательно читали тему (если читали):
Цитата Сообщение от Croessmah Посмотреть сообщение
Значит его нужно инициализировать один раз - при старте приложения.
Зачем в конструкторе каждый раз дергать его размер?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.04.2016, 01:16     Большой константный массив
Еще ссылки по теме:

очень большой массив C++
Большой двумерный массив как член класса C++
Константный метод и константный аргумент в методе C++
C++ Builder Большой массив объектов
C++ Константный массив в статичном поле класса

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
6859 / 4070 / 927
Регистрация: 30.01.2014
Сообщений: 6,867
05.04.2016, 01:16     Большой константный массив #14
Цитата Сообщение от pav1uxa Посмотреть сообщение
2) Очень тяжело сделать чтобы он заполнялся во время компиляции?
Создаваться он все равно будет в рантайме, т.к. это вектор. Но заполнение, вернее генерацию последовательности для заполнения, на этапе компиляции написать можно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <vector>
#include <utility>
 
template <size_t I>
struct TestGen
{ 
    static constexpr double value = 1000 + I * 3.14; 
};
 
template <typename T, template<size_t I> class Generator>
class filled_vector
    : public std::vector<T>
{
public:
    template <size_t ...Indexes>
    filled_vector(std::index_sequence<Indexes...>)
        : std::vector<T>{ Generator<Indexes>::value... }
    { }
};
 
class A
{
public:
    A() {}
    
    void check()
    {
        for(auto & c : x)
            std::cout << c << ' ';
    }
    
private:
    static const filled_vector<double, TestGen> x;
};
 
const filled_vector<double, TestGen> A::x{ std::make_index_sequence<1024>{} };
 
 
int main()
{
    A a;
    a.check();
}
Демка (С++14): http://rextester.com/KFSX33004
Можно повторить для С++11, но писанины будет чуть побольше. Это сами.

С другой стороны, коль у нас размер фиксирован (да и вектор константен), нет никаких препятствий использовать обычный массив. Принцип тот же. Да, я видел, что автору нужен вектор. Я не предлагаю ему массив. Просто говорю, что обычный массив тоже сгодится.

Не по теме:

PS. Разговоры про наследование (как в +, так и в -) от стандартного контейнера в данном контексте считаю оффтопиком.

Yandex
Объявления
05.04.2016, 01:16     Большой константный массив
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru