위임 생성자를 사용하는 동안 멤버 초기화


96

나는 C ++ 11 표준을 시도하기 시작했고 init 메소드 등을 피하기 위해 동일한 클래스의 다른 ctor에서 ctor를 호출하는 방법을 설명하는 질문을 발견 했습니다 . 이제 다음과 같은 코드로 동일한 작업을 시도하고 있습니다.

hpp :

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;. 하지만 이니셜 라이저 목록을 사용하고 싶습니다.

답변:


118

멤버 초기화를 다른 생성자에 위임 할 때 다른 생성자가 모든 멤버 (예 : 예제에 멤버 포함)를 포함 하여 객체를 완전히 초기화한다고 가정합니다 lines. 따라서 멤버를 다시 초기화 할 수 없습니다.

표준의 관련 인용문은 다음과 같습니다.

(§12.6.2 / 6) mem-initializer-list는 생성자의 클래스 자체를 나타내는 모든 class-or-decltype을 사용하여 생성자 클래스의 다른 생성자에 위임 할 수 있습니다. mem-initializer-id가 생성자의 클래스를 지정하면, 이것이 유일한 mem-initializer가됩니다 . 생성자는 위임 생성자이고에서 선택한 생성자는 대상 생성자입니다. [...]

먼저 인수를받는 생성자의 버전을 정의하여이 문제를 해결할 수 있습니다 .

Tokenizer::Tokenizer(std::stringstream *lines)
  : lines(lines)
{
}

위임을 사용하여 기본 생성자를 정의합니다.

Tokenizer::Tokenizer()
  : Tokenizer(nullptr)
{
}

일반적으로 가장 많은 수의 인수를 사용하는 생성자의 해당 버전을 완전히 지정한 다음 다른 버전에서 위임해야합니다 (위임에서 원하는 기본값을 인수로 사용).


2
처음에는 반 직관적으로 보이지만 실제로는 도움이됩니다!
Korchkidu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.