станд :: вектор & л; бар & GT; в качестве переменной-члена в классе Foo необходим пустой конструктор для Bar

Вот ситуация:

У меня есть класс, определенный следующими файлами.

Файл Foo.h:

template<typename MyType>
class Foo
{
public:
Foo(int number = 50);

private:
typedef enum {VAR1, VAR2} Type;

class Bar
{
MyType a;
Type b;

Bar(int param1, Type param2) : a(param1), b(param2) {}
}

std::vector<Bar> vec;
};

Файл Foo.cpp:

template<typename MyType>
Foo::Foo(int number) : vec(number)
{ }

Проблема в том, что когда я компилирую это, я получаю сообщение об ошибке в первой строке файла .cpp, говорящее о том, что ему нужен конструктор для Bar без аргументов. Я думаю, что это нужно для создания вектора в Foo. Я добавил конструктор без аргументов для Bar, предоставив следующий файл .h:

template<typename MyType>
class Foo
{
public:
Foo(int number = 50);

private:
typedef enum {VAR1, VAR2} Type;

class Bar
{
MyType a;
Type b;

Bar() {}   // <----  Line added
Bar(int param1, Type param2) : a(param1), b(param2) {}
}

std::vector<Bar> vec;
};

Теперь я могу скомпилировать, и это работает, но в строке, которую я только что добавил, есть предупреждение о том, что Member 'b' was no initialized in this constructor, Может, проблема с enum?

Я не понимаю, что я должен сделать, чтобы заставить это работать без этого предупреждения.

редактировать : Я получил несколько ответов, в которых говорилось о добавлении списка инициализации в пустой конструктор. Тем не менее, мой класс на самом деле является шаблоном класса и a это неизвестный тип для меня, поэтому я не могу инициализировать его, так как я не знаю его тип. Я пробовал только инициализировать b в списке инициализации в баре, и это сработало. Предупреждение исчезло, но можно ли a неинициализированный? Будет ли способ удалить конструктор без аргумента Bar и все же дать размер вектору в конструкторе Foo?

2

Решение

Проблема заключается в списке инициализатора в определении Foo::Foo(int), Ты пишешь

Foo::Foo(int n)
: vec(n) { }

то есть вы используете конструктор

std::vector<Bar>::vector(size_t number, const Bar &x = Bar())

Обратите внимание, что x = Bar() это означает, что вы заполняете вектор стандартными построенными экземплярами Bar, Так как есть по крайней мере один конструктор, определенный в Bar компилятор не предоставляет автоматически стандартный конструктор.

Определите стандартный конструктор в Bar как другие ответы предлагают или положить что-то еще в конструкторе Fooнапример это

Foo::Foo(int n)
: vec(n, Bar(1, VAR1)) { }

и ошибка компилятора исчезает.

Ответ на ваше редактирование: Предупреждение, которое вы получаете, вероятно, означает: участник a не правильно инициализирован. Так как это int это может быть хорошо (C ++ не заставляет вас инициализировать intс). Но остерегайтесь странных и произвольных значений в члене a позже в вашей программе. Лучшее решение состоит в том, чтобы установить его во время создания в четко определенное состояние, что означает для вас «это значение неизвестно».

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

Вы можете инициализировать a в стандартном конструкторе Bar как это:

Bar::Bar() : a(MyType()), b(UNKNOWN) { }

и добавив UNKNOWN к перечислению Type, Это предполагает тип MyType стандартно конструктивен Это относится, например, ко всем примитивным типам, таким как int, doubleи т. д. Это дает вам четко определенное состояние Bar объект, который может значить для вас неизвестный. Это можно проверить, сравнив b в UNKNOWN,

Как сказал Якк в своем комментарии: Примитивные типы, такие как перечисления, можно оставить унифицированными, но в вашем случае компилятор предупреждает вас: это может быть ваш член b содержит значение, которое не имеет метки, как VAR1 или же VAR2 совсем. Это всегда хорошая идея инициализировать все члены с четко определенными значениями, если вы действительно не обязаны этого делать — например, если выполнение является чертовски важным.

6

Другие решения

Вам нужно добавить список инициализации в пустой конструктор (и, возможно, сделать его общедоступным).

class Bar
{
int a;
Type b;

Bar() : a(0), b(VAR1) {}   // initialize the members to default values.
Bar(int param1, Type param2) : a(param1), b(param2) {}
}
0

По вопросам рекламы [email protected]