#c #arrays #class
#c #массивы #класс
Вопрос:
class foo {
public:
const char name[100];
foo(const char name[]) : name(name) {};
};
int main(){
foo("test");
return 0;
}
Не компилируется. Как мне инициализировать const char[]
нестатический член класса?
Комментарии:
1.
memcpy
это ваш друг.char name[100]
является анахронизмом C, используемымstd::aray<char, 100>
в C .2.
std::string
выглядит более подходящим. Массивы действительно глупы. они были разработаны для решения проблем 1970-х годов, и они отлично справляются с этой задачей, но если вам нужна магия, которую вы получаете от более недавно разработанных языков, таких как Java или Python, вам нужно использовать библиотечные контейнеры C3. Вам придется переместить этот массив в отдельный класс, который имеет свой собственный конструктор, принимающий a
char const*
, и никак иначе (кроме evilconst_cast
).
Ответ №1:
У вас есть разные варианты, в зависимости от того, чего вы хотите достичь.
массивы в C — странные звери, они ведут себя не так, как большинство других типов, в частности, они распадаются на указатели и не имеют конструкторов копирования (если только они не завернуты в структуру / класс).
foo(const char name[])
не принимает массив по значению / по копии, он принимает указатель (да, синтаксис сбивает с толку).
Таким образом name(name)
, он пытается инициализировать массив с помощью указателя. Если бы это было скомпилировано, это сделало бы очень простым случайное переполнение стека, поскольку нет никакой гарантии, что имя указателя указывает на массив длиной не более 100 элементов.
Решение 1
Используйте более подходящую конструкцию — используйте строку.
Из вашего фрагмента кажется, что вы хотите сохранить фрагмент текста (переменная с именем name
, инициализация строковым литералом …), Поэтому std::string или другой строковый класс (даже const char*
) является лучшей конструкцией.
class foo {
public:
std::string name;
explicit foo(std::string name_) : name(name_) {};
};
int main(){
foo("test");
}
Решение 2
Используйте лучший массив
Если вам действительно нужно сохранить / скопировать массив, рассмотрите возможность использования std::array
(начиная с c 11)
#include <array>
class foo {
public:
std::array<char, 100> name;
explicit foo(std::array<char, 100> name_) : name(name_) {};
};
int main(){
foo(std::array<char, 100>{"test"});
}
Решение 3
Передайте массив с помощью const-ref.
Существуют случаи использования—, когда вы действительно хотите использовать массив. В этом случае вам нужно передать значение по ссылке и скопировать содержимое с помощью std::initializer_list (начиная с c 14, но его можно эмулировать в c 11)
#include <utility>
class foo {
template <std::size_t... PACK1>
explicit foo(const char (amp;name_)[100], std::index_sequence<PACK1...>)
: name{ name_[PACK1]... }
{}
const char name[100];
public:
explicit foo(const char (amp;name_)[100])
: foo(name_, std::make_index_sequence<100>{})
{}
};
int main(){
const char hello[100] = "hello!";
foo f = foo(hello);
}
const char (amp;arr)[100]
это массив длиной 100, передаваемый с помощью const-reference .
Поскольку массивы не имеют конструкторов копирования, нам нужно использовать index_sequence
для инициализации всех членов.
Решение 4
Используйте указатели и инициализируйте массив в 2 этапа.
Передача массива с помощью const-reference означает, что вам нужно заранее создать такой большой массив, и что вы не можете передать строковый литерал, длина которого не равна 101 (из-за terminatig
).
#include <cstring>
class foo {
const char name[100];
public:
// constructor requires copy... unsure if needs to be so
explicit foo(const char* name_)
{
std::copy(name_, name_ std::strlen(name_), name);
}
};
int main(){
const char test[100] = "test!";
foo f = foo(test);
}
Ответ №2:
я бы предложил использовать a std::string
, если вы используете c , но если const char []
это необходимо, вот решение, в основном вы просто копируете некоторую часть кратчайшей строки в массив size 100
, оставляя незаполненным дополнительное пространство (т. Е. name
Приведет к name = ['t','e','s','t','',...]
https://www.cplusplus.com/reference/cstring/memcpy /