Quero redefinir os operadores new e delete para usar um alocador personalizado em um projeto C++ com múltiplas unidades de tradução. Aqui estão as redefinições escritas no arquivo memops.hpp:
#pragma once
#include "../lib/mem.h"
void* operator new(size_t size) {
return __mem_alloc(size);
}
void operator delete(void *ptr) {
__mem_free(ptr);
}
void* operator new[](size_t size) {
return __mem_alloc(size);
}
void operator delete[](void *ptr) {
__mem_free(ptr);
}
Minha pergunta é: onde incluir este arquivo de cabeçalho? Faz alguma diferença? A definição alternativa é aplicada em todos os lugares do projeto?
Encontrei este artigo https://www.ibm.com/docs/en/i/7.4?topic=heap-overloading-new-delete-operator , mas o último parágrafo me confunde.
O local onde você inclui memops.hpp com alocadores personalizados importa, dependendo de como você está redefinindo os operadores globais new e delete .
Em C++, quando você define o operador global new / operador delete em uma unidade de tradução, esses se tornam os operadores globais para todo o programa - se e somente se esses forem os vinculados ao executável final.
No entanto, você deve ter em mente que se colocar essa definição em um cabeçalho e incluÃ-la em vários arquivos .cpp, você obterá várias definições — violando a Regra de Uma Definição (ODR).
Além disso, sugiro que você declare métodos apenas no arquivo de cabeçalho e escreva a implementação no único arquivo .cpp.
Portanto, memops.hpp ficará assim:
E memops.cpp:
Dessa forma, sobrecargas globais são definidas exatamente uma vez, então o vinculador as aplicará a todos os usos de new e delete no seu programa, desde que nenhuma outra unidade de tradução forneça uma definição diferente.
Sobre o último parágrafo do artigo, creio que isso se aplica principalmente ao contexto de bibliotecas compartilhadas, onde sÃmbolos globais não podem se propagar para outros módulos, a menos que sejam explicitamente vinculados ou incluÃdos. Em projetos C++ padrão, especialmente com vinculação estática, definir as sobrecargas em uma unidade de tradução é suficiente.