С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242

Массив в заголовке класса

08.10.2022, 13:45. Показов 1894. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Хотел я тут недавно создать массив в заголовочном файле класса таким образом:
C++
1
2
    const int size = 10;
    int arr[size];
Но если в мэйне всё работает, то почему-то в заголовке выдаёт ошибку "нестатическая ссылка не член должна указываться относительно заданного объекта". При этом если просто написать
C++
1
int arr[10];
, то всё работает. Я вышел из положения, создав в конструкторе динамический массив размера size. Но мне интересно, почему нельзя создать массив в заголовке таким способом и почему появляется эта ошибка?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.10.2022, 13:45
Ответы с готовыми решениями:

Зачем нужно опережающее объявление класса в заголовке?
Часто натыкаюсь на такой код: class NewType; class Class1 { public: Class1(); private: NewType *field; };

Unresolved external и использование класса находящегося в заголовке
Есть объявление класса библиотеки FTGL - CFont (line 37), и использование его в функции RenderScene (line 75) и это приводит к Unresolved...

После Протокол, используемое в заголовке IPv4 отсутствует в фиксированном заголовке IPv6. Почему ?
После Протокол, используемое в заголовке IPv4 отсутствует в фиксированном заголовке IPv6. Почему ?

21
2393 / 1914 / 763
Регистрация: 27.07.2012
Сообщений: 5,558
08.10.2022, 13:51
Цитата Сообщение от Ballantrae Посмотреть сообщение
Я вышел из положения, создав в конструкторе динамический массив размера size. Но мне интересно, почему нельзя создать массив в заголовке таким способом и почему появляется эта ошибка?
Ничё не понятно. Какой конструктор? Где создаётся массив? Приведите код полностью.
0
фрилансер
 Аватар для Алексей1153
6447 / 5643 / 1128
Регистрация: 11.10.2019
Сообщений: 15,016
08.10.2022, 15:23
Цитата Сообщение от Ballantrae Посмотреть сообщение
почему нельзя создать массив в заголовке
где-то в каком-то заголовке:

C++
1
2
constexpr size_t size = 10;
inline int arr[size];
1
Модератор
Эксперт С++
 Аватар для zss
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
08.10.2022, 15:38
А не лучше ли использовать шаблонный параметр
C++
1
2
3
4
5
6
7
8
9
10
template<int size>
class A
{
   int arr[size];
....
};
int main()
{
    A<10> a;
}
0
Заблокирован
08.10.2022, 15:47
Цитата Сообщение от zss Посмотреть сообщение
А не лучше ли использовать шаблонный параметр
Если размер массива заранее известен, то это просто не нужно.
А отдельно объявить размер массива вполне разумно, для его дальнейшего использования в коде.

Цитата Сообщение от John Prick Посмотреть сообщение
Ничё не понятно
+1
0
фрилансер
 Аватар для Алексей1153
6447 / 5643 / 1128
Регистрация: 11.10.2019
Сообщений: 15,016
08.10.2022, 17:01
Цитата Сообщение от SmallEvil Посмотреть сообщение
отдельно объявить размер массива
особо смысла не имеет, поскольку есть std::size
0
Заблокирован
08.10.2022, 18:26
Цитата Сообщение от Алексей1153 Посмотреть сообщение
особо смысла не имеет, поскольку есть std::size
я имел ввиду
C++
1
2
constexpr size_t size = 10;
inline int arr[size];
против
C++
1
   int arr[10];
Добавлено через 54 секунды
Цитата Сообщение от Алексей1153 Посмотреть сообщение
особо смысла не имеет, поскольку есть std::size
имеет, если отдается как указатель на массив, да и в других случаях тоже может понадобится.

Добавлено через 22 секунды
Хотя, да, дело вкуса.
0
фрилансер
 Аватар для Алексей1153
6447 / 5643 / 1128
Регистрация: 11.10.2019
Сообщений: 15,016
08.10.2022, 18:40
Цитата Сообщение от SmallEvil Посмотреть сообщение
если отдается как указатель на массив
там, где такое понадобилось, также обычно требуется передать и размер. Его туда можно передать при помощи std::size. И в других случаях тоже

Лучше, конечно, использовать std::array
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.10.2022, 18:45
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Лучше, конечно, использовать std::array
чем лучше?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
08.10.2022, 21:27
Цитата Сообщение от Ballantrae Посмотреть сообщение
Добрый день. Хотел я тут недавно создать массив в заголовочном файле класса таким образом:
C++
1
2
    const int size = 10;
    int arr[size];
Если это написано внутри определения класса - то так и скажите. И приведите определение класса.

При чем здесь "заговлочный файл" - не ясно.

Цитата Сообщение от Ballantrae Посмотреть сообщение
Но если в мэйне всё работает, то почему-то в заголовке выдаёт ошибку "нестатическая ссылка не член должна указываться относительно заданного объекта".
...
Но мне интересно, почему нельзя создать массив в заголовке таким способом и почему появляется эта ошибка?
Размер массива в объявлении массива в С++ должен быть константой времени комиляции. В вашем примере нельзя использовать поле size для указания размера массива, потому что значение поля size не известно на стадии компиляции.
0
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
09.10.2022, 22:04  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
Ничё не понятно. Какой конструктор? Где создаётся массив? Приведите код полностью.
MyClass.h
C++
1
2
3
4
5
6
class MyClass
{
     const int size = 10;
     int arr[size]; // Так не компилируется
     int arr[10]; // Вот так компилируется.
}
Про конструктор. Сделал вот так:

MyClass.h
C++
1
2
3
4
5
class MyClass
{
     const int size = 10;
     int* arr;
}
MyClass.cpp
C++
1
2
3
4
MyClass::MyClass()
{
arr = new int[size];
}
Добавлено через 5 часов 18 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Размер массива в объявлении массива в С++ должен быть константой времени комиляции. В вашем примере нельзя использовать поле size для указания размера массива, потому что значение поля size не известно на стадии компиляции.
Почему не известно? У меня ведь написано
C++
1
2
const int size = 10;
int arr[size];
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
09.10.2022, 22:13
Цитата Сообщение от Ballantrae Посмотреть сообщение
Почему не известно? У меня ведь написано
Потому что инициализация size будет на этапе исполнения.
0
Заблокирован
09.10.2022, 22:16
Цитата Сообщение от Ballantrae Посмотреть сообщение
У меня ведь написано
На заборе тоже много чего написано.

size будет известен только после создания объекта класса MyClass.
А это рантайм.

Пример :
C++
1
2
3
4
5
struct MyStuct{
   const int a = 10;
   MyStuct(){};
   MyStruct(int b):a{b}{};
};
Теперь при вызове конструктора с параметром, a будет такое значение, которое мы ему зададим через этот самый параметр.
спецификатор cons не гарантирует что переменная будет времени компилетайм.
Она гарантирует лишь неизменность переменной, после ее инициализации.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
09.10.2022, 22:22
Цитата Сообщение от Ballantrae Посмотреть сообщение
Почему не известно? У меня ведь написано
C++
1
2
const int size = 10;
int arr[size];
И что из этого? Инициализатор нестатического члена класса никак не "фиксирует" его значение и не делает его "известным". В одном месте может быть написано один инициализатор, в другом - другой. Компилятор не знает, какое именно значение получит член класса при создении конкретного объекта. Ваше = 10 - это не более чем инициализатор по умолчанию.

Например

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
struct S
{
  const int a = 10;
  S() : a(20) {}
};
 
int main()
{
  S s;
  std::cout << s.a << std::endl;
}
Что напечатает этот код?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
09.10.2022, 22:38
Лучший ответ Сообщение было отмечено Ballantrae как решение

Решение

Ballantrae, в дополнение к предыдущим ответам, определить константу времени компиляции в class scope можно так:
C++
1
2
3
4
5
class MyClass
{
     static constexpr int size = 10;
     int arr[size]; // ок
};
0
10.10.2022, 07:59

Не по теме:

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Инициализатор нестатического члена класса никак не "фиксирует" его значение и не делает его "известным"
Какой кошмар. Я всегда думал, что константы должны работать как константы в математике — их значение зафиксировано на этапе написания кода и соответственно компиляции.
А оказывается, в Си Плас Плас константа — это переменная.
Мда.

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
10.10.2022, 08:15
Цитата Сообщение от Замабувараев Посмотреть сообщение
Я всегда думал, что константы должны работать как константы в математике — их значение зафиксировано на этапе написания кода и соответственно компиляции.
Нет, в языке С++ константный объект - это объект, значение которого зафиксировано в момент его создания в процессе выполнения программы, а не на этапе написания кода.

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

В данном случае рассматриваемое поле size - нестатический член класса - этим требованиям не удовлетворяет.
0
 Аватар для ram876
759 / 456 / 213
Регистрация: 19.12.2016
Сообщений: 1,815
10.10.2022, 08:40
А еще есть такая страшная вещь:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
int main()
{
    const int a = 4;
    const_cast<int&> (a) = 5;
    const int& b = a;
    std::cout << a;
    std::cout << b;
    return 0;
}
Правда я не понимаю зачем она нужна, если ее очень опасно применять.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
10.10.2022, 08:57
ram876, вы неправильно ее применяете. Снимать константность с константного объекта для последующей записи не допускается. Снимать константность для записи можно у константных ссылок изначально привязанных к неконстантному объекту, например. Либо с изначально константных объектов, но с гарантией, что записи туда не будет.
1
 Аватар для ram876
759 / 456 / 213
Регистрация: 19.12.2016
Сообщений: 1,815
10.10.2022, 09:06
DrOffset, я лучше буду обходить стороной эту возможность. Видится мне, что есть большая вероятность допустить ошибку (особенно с моей невнимательностью).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.10.2022, 09:06
Помогаю со студенческими работами здесь

В заголовке функции описать параметр - двумерный массив строк
Как в заголовке функции описать параметр - двумерный массив строк постоянной длины. Описать переменную через variant в данном случае не...

Массив объектов одного класса как поле другого класса
Доброе время суток. Мне тут в универе задали лабу, нужно создать класс полем которого будет массив объектов класса из предыдущей лабы и в...

Как переместить из стека одного класса в массив другого класса?
// HW_on.24.11_classStack_SantaClaus.cpp: определяет точку входа для консольного приложения. // #include &quot;stdafx.h&quot; ...

Как правильно создать массив объектов текущего класса в методе данного класса?
Привет! Ставится задача создания метода, который формирует массив объектов. Правильно ли делать этот метод внутри класса, экземпляром...

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru