Инициализация элемента при использовании делегированного конструктора
я начал пробовать стандарт C++11, и я нашел этой вопрос, который описывает, как вызвать ваш ctor из другого ctor в том же классе, чтобы избежать наличия метода init или тому подобного. Сейчас я пытаюсь то же самое с кодом, который выглядит так:
ГЭС:
class Tokenizer
{
public:
Tokenizer();
Tokenizer(std::stringstream *lines);
virtual ~Tokenizer() {};
private:
std::stringstream *lines;
};
cpp:
Tokenizer::Tokenizer()
: expected('=')
{
}
Tokenizer::Tokenizer(std::stringstream *lines)
: Tokenizer(),
lines(lines)
{
}
но это дает мне ошибку:
In constructor ‘config::Tokenizer::Tokenizer(std::stringstream*)’:
/path/Tokenizer.cpp:14:20: error: mem-initializer for ‘config::Tokenizer::lines’ follows constructor delegation
Я попытался переместить часть Tokenizer () первой и последней в списке, но это не так помощь.
в чем причина этого и как я должен это исправить? Я пробовал двигать lines(lines)
тело с this->lines = lines;
вместо этого, и он отлично работает. Но я действительно хотел бы иметь возможность использовать список инициализаторов.
спасибо заранее!
1 ответ:
когда вы делегируете инициализацию члена другому конструктору, есть предположение, что другой конструктор инициализирует объект полностью, включая все члены (т. е. включая
lines
член в вашем примере). Поэтому вы не можете инициализировать любой из членов снова.соответствующая цитата из стандарта (выделено мной):
(§12.6.2 / 6) mem-инициализатор-список может делегировать другому конструктору класс конструктора, используя любой класс или decltype, который обозначает сам класс конструктора. Если mem-initializer-id обозначает класс конструктора,это будет единственный mem-инициализатор; конструктор является делегирующим конструктором,а конструктор, выбранный целевым конструктором. [...]
вы можете обойти это, определив версию конструктора, который принимает аргументы первый:
Tokenizer::Tokenizer(std::stringstream *lines) : lines(lines) { }
и затем определите конструктор по умолчанию с помощью делегирования:
Tokenizer::Tokenizer() : Tokenizer(nullptr) { }
как правило, вы должны полностью указать ту версию конструктора, которая принимает наибольшее количество аргументов, а затем делегировать из других версий (используя желаемые значения по умолчанию в качестве аргументов в делегировании).