Como evito que uma class seja alocada através do operador ‘new’? (Eu gostaria de garantir que minha class RAII esteja sempre alocada na pilha.)

Eu gostaria de garantir que minha class RAII esteja sempre alocada na pilha.

Como evito que uma class seja alocada através do operador ‘new’?

Tudo o que você precisa fazer é declarar o novo operador da class como privado:

class X { private: // Prevent heap allocation void * operator new (size_t); void * operator new[] (size_t); void operator delete (void *); void operator delete[] (void*); // ... // The rest of the implementation for X // ... }; 

Tornar o ‘operador novo’ privado efetivamente impede que o código fora da class use ‘novo’ para criar uma instância do X.

Para completar, você deve ocultar ‘delete do operador’ e as versões do array de ambos os operadores.

Desde C ++ 11, você também pode excluir explicitamente as funções:

 class X { // public, protected, private ... does not matter static void *operator new (size_t) = delete; static void *operator new[] (size_t) = delete; static void operator delete (void*) = delete; static void operator delete[](void*) = delete; }; 

Pergunta relacionada: É possível evitar a alocação de pilha de um object e permitir que seja instanciado com ‘novo’?

Não estou convencido da sua motivação.

Existem boas razões para criar aulas de RAII na loja gratuita.

Por exemplo, eu tenho uma class de bloqueio RAII. Eu tenho um caminho através do código onde o bloqueio é necessário somente se certas condições forem seguras (é um player de vídeo, e eu só preciso segurar o bloqueio durante o meu loop de renderização se eu tiver um vídeo carregado e reproduzido; se nada estiver carregado, Eu não preciso disso). A capacidade de criar bloqueios no armazenamento gratuito (com um scoped_ptr / auto_ptr) é, portanto, muito útil; Ele permite que eu use o mesmo caminho de código, independentemente de eu ter que remover o bloqueio.

ou seja, algo assim:

 auto_ptr l; if(needs_lock) { l.reset(new lock(mtx)); } render(); 

Se eu pudesse criar apenas bloqueios na pilha, eu não poderia fazer isso ….

@DrPizza:

Esse é um ponto interessante que você tem. Note, porém, que existem algumas situações em que o idioma RAII não é necessariamente opcional.

De qualquer forma, talvez a melhor maneira de abordar seu dilema é adicionar um parâmetro ao seu construtor de bloqueio que indica se o bloqueio é necessário. Por exemplo:

 class optional_lock { mutex& m; bool dolock; public: optional_lock(mutex& m_, bool dolock_) : m(m_) , dolock(dolock_) { if (dolock) m.lock(); } ~optional_lock() { if (dolock) m.unlock(); } }; 

Então você poderia escrever:

 optional_lock l(mtx, needs_lock); render(); 

Na minha situação particular, se a fechadura não é necessária, o mutex nem existe, então acho que essa abordagem seria mais difícil de encheckboxr.

Eu acho que a coisa que eu realmente estou tentando entender é a justificativa para proibir a criação desses objects na free store.