Последнее обновление: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();
}
Похожие темы¶
- C++ чисто виртуальные функции и абстрактные классы | C++那些事
- C++ утверждения assert | C++那些事
- C++ битовые поля | C++那些事
- Реализация полиморфизма C++ на языке C | C++那些事
- C++ константы const и его модификация | C++那些事
- C++ всё семейство const | C++那些事
- C++ оператор разыменования * | C++那些事
- C++ инициализация и присваивание | C++那些事
- C++ возврат нескольких значений | C++那些事
- C++ ключевое слово mutable | C++那些事