Saltar a contenido

Última actualización:2026-10-12

C++20 [[no_unique_address]]

C++那些事: optimización de memoria

Normalmente, la memoria en tiempo de ejecución es un problema considerable: reducir el consumo de memoria y acelerar el acceso resultan cruciales. Para resolver estos problemas, C++20 introdujo la característica no_unique_address que, combinada con la optimización de clase base vacía (EBO, Empty Base Optimization), ofrece a quienes desarrollan una forma eficaz de optimizar la disposición de la memoria.

1. Optimización de clase base vacía (EBO)

EBO significa que la presencia de una clase base vacía (es decir, una clase sin miembros de datos) en una clase derivada no ocupa memoria adicional. El compilador de C++ fusiona las instancias de estas clases base vacías, evitando costes de memoria innecesarios. Esto resulta especialmente útil al diseñar jerarquías de clases complejas, ya que puede reducir eficazmente el tamaño de los objetos.

#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;
}

En el código anterior, la clase Derived ocupa en memoria solo el tamaño de un int, y no el tamaño de int más Empty. Esto se debe a que el compilador aprovecha la característica EBO.

¿Adivinas cuál es la salida anterior?

2. La característica no_unique_address

C++20 introdujo la característica no_unique_address, que permite marcar explícitamente determinados miembros de una clase para que no ocupen espacio adicional en memoria. Resulta especialmente adecuada para «objetos de 0 bytes»; por ejemplo:

En un unique_ptr, cuando el Deleter es un struct/clase vacío, el sizeof obtenido es 16; a partir de C++20 puede dejar de ocupar bytes, y el sizeof total pasa a ser 8.

template<class T, class Deleter>
class unique_ptr {
    T* pointer = nullptr;
    [[no_unique_address]] Deleter deleter;

   public:
    // 其他成员函数...
};

Fin de esta sección

Temas relacionados

Comentarios