Перейти к содержанию

Последнее обновление:2026-10-12

C++ тонкости списка инициализации членов

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

Список инициализации обычно считается предпочтительным способом задания состояния нового экземпляра класса, поскольку он даёт лаконичный и эффективный способ инициализации членов класса. Однако иногда ссылки на другие переменные-члены в списке инициализации могут приводить к запутанным проблемам.

Пример проблемы

Рассмотрим следующий класс Foo:

#include <iostream>

class Foo
{
public:
  Foo(int size) : size_(size),
                 capacity_(size_ + 2),
                 length_(capacity_)
  {}

  void print() {
    std::cout << "Size: " << size_ << " Capacity:  " << capacity_ << " Length: " << length_  << std::endl;
  }

private:
  int length_;
  int capacity_;
  int size_;
};

int main() {
  Foo foo(50);
  foo.print();
}

В этом примере мы пытаемся инициализировать length_, capacity_ и size_, ссылаясь в списке инициализации на другие переменные-члены. Однако поскольку порядок инициализации членов класса определяется порядком их объявления в классе, length_ и capacity_ могут быть инициализированы не так, как мы ожидаем.

Как решить?

Чтобы избежать такой проблемы, следует придерживаться следующих пунктов:

1.Избегайте ссылок на другие переменные-члены в списке инициализации

2.Согласованность порядка: переменные-члены инициализируются в порядке их объявления в классе

Исправленный пример:

#include <iostream>

class Foo
{
public:
  Foo(int size) : size_(size),
                 capacity_(size_ + 2),
                 length_(calculateLength(size_))
  {}

  void print() {
    std::cout << "Size: " << size_ << " Capacity:  " << capacity_ << " Length: " << length_  << std::endl;
  }

private:
  int calculateLength(int size) {
    return size + 2;
  }

private:
  int size_;
  int capacity_;
  int length_;
};

int main() {
  Foo foo(50);
  foo.print();
}

Похожие темы

Комментарии