Последнее обновление:2026-10-12
[[no_unique_address]] в C++20¶
C++那些事 — оптимизация памяти¶
Обычно память во время работы программы является весьма серьёзным вопросом: уменьшение объёма используемой памяти и повышение скорости доступа критически важны. Для решения этих проблем C++20 ввёл возможность no_unique_address, которая в сочетании с оптимизацией пустой базы (EBO, Empty Base Optimization) даёт разработчикам эффективный способ оптимизировать раскладку памяти.
1. Оптимизация пустой базы (EBO)¶
EBO означает, что пустой базовый класс (то есть класс без членов данных) не занимает дополнительной памяти в производном классе. Компилятор C++ объединяет экземпляры таких пустых базовых классов, избегая лишних накладных расходов памяти. Это особенно полезно при проектировании сложных иерархий классов и позволяет эффективно уменьшить размер объектов.
#include <iostream>
class Empty {};
class Derived : public Empty {
int value;
public:
Derived(int v) : value(v) {}
};
class Test {
int value;
public:
Test(int v) : value(v) {}
Empty e;
};
int main() {
std::cout << sizeof(Derived) << std::endl;
std::cout << sizeof(Test) << std::endl;
return 0;
}
В приведённом выше коде класс Derived занимает в памяти лишь размер int, а не размер int плюс размер Empty. Это происходит потому, что компилятор использует свойство EBO.
Как вы думаете, что выведет приведённый выше код?
2. Возможность no_unique_address¶
В C++20 появилась возможность no_unique_address, которая позволяет явно помечать определённые члены класса так, чтобы они не занимали дополнительного места в памяти. Особенно это подходит для объектов размером 0 байт, например:
В unique_ptr, когда Deleter — пустая структура/класс, получаемый sizeof равен 16; после C++20 он может не занимать байтов, и весь sizeof станет равен 8.
template<class T, class Deleter>
class unique_ptr {
T* pointer = nullptr;
[[no_unique_address]] Deleter deleter;
public:
// 其他成员函数...
};
На этом раздел закончен
Похожие темы¶
- Введение в корутины C++20 | C++那些事
- Практика с channel в C++20 | C++那些事
- Концепции Concepts в C++20 | C++那些事
- constexpr и оператор «запятая» в C++20 | C++那些事
- Порядок байтов endian в C++20 | C++那些事
- Лямбда-выражения в C++20 (часть 1) | C++那些事
- Модули Modules в C++20 | C++那些事
- Библиотека Ranges в C++20 | C++那些事
- Дизайн и подводные камни std::span в C++20 | C++那些事
- Обзор новых возможностей C++20 | C++那些事