Как мне использовать функции-члены постоянных массивов в C ++?

StackOverflow https://stackoverflow.com/questions/1639393

  •  08-07-2019
  •  | 
  •  

Вопрос

Вот упрощенная версия того, что у меня есть (не работает):

прогр.ч:

...
const string c_strExample1 = "ex1";
const string c_strExample2 = "ex2";
const string c_astrExamples[] = {c_strExample1, c_strExample2};
...

prog.cpp:

...
int main()
{
    int nLength = c_astrExamples.length();
    for (int i = 0; i < nLength; i++)
        cout << c_astrExamples[i] << "\n";
    return 0;
}
...

Когда я пытаюсь выполнить сборку, я получаю следующую ошибку:ошибка C2228:слева от '.length' должен быть класс / структура / объединение

Ошибка возникает только тогда, когда я пытаюсь использовать функции-члены c_astrExamples.Если я заменю "c_astrExamples.length()" на число 2, все, похоже, будет работать правильно.

Я могу использовать функции-члены c_strExample1 и c_strExample2, поэтому я думаю, что поведение возникает из-за некоторой разницы между моим использованием строк и массивов строк.

Является ли моя инициализация в prog.h неправильной?Нужно ли мне что-то особенное в prog.cpp?

Это было полезно?

Решение

Массивы в C ++ не имеют функций-членов.Вы должны использовать коллекцию, подобную vector<string> если вам нужен объект, или вычислите длину следующим образом:

int nLength = sizeof(c_astrExamples)/sizeof(c_astrExamples[0]);

Другие советы

Просто используй Вектор STL из строк вместо массива:

#include <string>
#include <vector>
using namespace std;

const string c_strExample1 = "ex1";
const string c_strExample2 = "ex2";
vector<string> c_astrExamples;
c_astrExamples.push_back(c_strExample1);
c_astrExamples.push_back(c_strExample2);

int main()
{
    int nLength = c_astrExamples.size();

Массивы в C ++ унаследованы от C, который не был объектно-ориентированным.Таким образом, они не являются объектами и не имеют функций-членов.(В том, что они ведут себя как int, float и другие встроенные типы.) Из этой родословной вытекает больше проблем с array, таких как тот факт, что они легко (например, при передаче в функцию) распадаются на указатель на первый элемент без оставшейся информации о размере.

Обычный совет заключается в том, чтобы использовать std::vector вместо этого, который представляет собой массив с динамически изменяемым размером.Однако, если вам размер массива известен во время компиляции и вам нужна константа, то тип массива boost'а (boost::array, если ваш компилятор поддерживает стандартные расширения TR1 , также доступные как std::tr1::array, стать std::array в следующей версии стандарта C ++) - это то, что вы хотите.

Правка 1:

Безопасный способ получить длину массива в C ++ включает невероятную комбинацию шаблонов, указателей на функции и даже макроса, добавленного в смесь:

template <typename T, std::size_t N>
char (&array_size_helper(T (&)[N]))[N];

#define ARRAY_SIZE(Array_) (sizeof( array_size_helper(Array_) ))

Если вы (как и я) считаете это забавным, посмотрите на boost::array.

Правка 2:

Как сказал дрибеас в комментарии, если вам не нужна константа времени компиляции, это

template <typename T, std::size_t N>
inline std::size_t array_size(T(&)[N])
{return N;}

этого достаточно (и гораздо легче читать и понимать).

c_astrExamples - это массив, в нем нет метода "length()".

В C ++ массивы не являются объектами и не имеют к ним никаких методов.Если вам нужно получить длину массива, вы могли бы использовать следующий макрос

#define COUNTOF( array ) ( sizeof( array )/sizeof( array[0] ) )
int nLength = COUNTOF(c_astrExamples);

Кроме того, остерегайтесь инициализации в заголовочном файле.Вы рискуете оскорбить компоновщика.
Тебе следовало бы:

прогр.ч:

extern const string c_strExample1;
extern const string c_strExample2;
extern const string c_astrExamples[];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top