Ir para o conteúdo

Última atualização:2026-10-12

[[no_unique_address]] no C++20

Otimização de memória em C++那些事

Normalmente, a memória durante a execução do programa é um problema considerável: como reduzir o consumo de memória e aumentar a velocidade de acesso é crucial. Para resolver esses problemas, o C++20 introduziu o recurso no_unique_address, combinado com a otimização de classe base vazia (EBO, Empty Base Optimization), oferecendo aos desenvolvedores uma forma eficaz de otimizar o layout de memória.

1. Otimização de classe base vazia (EBO)

EBO significa que a existência de uma classe base vazia (ou seja, sem membros de dados) na classe derivada não ocupa memória adicional. O compilador C++ mescla as instâncias dessas classes base vazias, evitando overhead de memória desnecessário. Isso é especialmente útil ao projetar hierarquias de classes complexas, podendo reduzir efetivamente o tamanho dos 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;
}

No código acima, a classe Derived ocupa na memória apenas o tamanho de um int, e não o tamanho de int somado a Empty. Isso acontece porque o compilador aproveita a característica do EBO.

Então, consegue adivinhar qual é a saída acima?

2. O recurso no_unique_address

O C++20 introduziu o recurso no_unique_address, que nos permite marcar explicitamente determinados membros de classe para que não ocupem espaço adicional na memória. É especialmente adequado para objetos de 0 bytes; por exemplo:

No unique_ptr, quando o Deleter é uma estrutura/classe vazia, o sizeof obtido é 16; a partir do C++20, ele pode não ocupar bytes, e o sizeof total fica em 8.

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

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

Fim desta seção

Tópicos relacionados

Comentários