Depende de onde você está no ciclo de desenvolvimento, mas às vezes, ao esboçar um algoritmo, você deseja abstrair sobre blocos complexos sem implementá-los imediatamente.
def full_algo():
init_stuff()
process_stuff()
...
Você sabe como init_stuff
vai funcionar, é bastante simples na sua cabeça, mas você realmente não precisa disso imediatamente, então a declara como uma função vazia. Isso permitirá que seu código seja compilado e executado sem se preocupar com os detalhes sangrentos.
Outro uso para aplicativos liberados é ao usar herança. Suponha que você tenha uma classe grande que define o comportamento do código específico da plataforma. Você pode acabar com uma lógica semelhante a esta:
init_filesystem();
access_files();
release_filesystem();
Esse código funcionará em muitas plataformas, mas algumas plataformas podem não precisar da inicialização do sistema de arquivos. Então sua herança ficará assim (virtual com = 0 em C ++ significa apenas que as classes derivadas DEVEM implementar esses métodos):
class FileSystem{
virtual void init_filesystem() = 0;
virtual void access_files() = 0;
virtual void release_filesystem() = 0;
};
Então, uma implementação específica dessa classe (interface) pode não fazer nada para alguns desses métodos. Como alternativa, a classe base poderia declarar métodos vazios para init / release em vez de declará-los virtuais.
Finalmente (e vergonhosamente), às vezes você mantém um aplicativo muito antigo. Você teme que os métodos de exclusão quebrem as coisas. Isso acontece quando você tem uma herança complexa que não é entendida corretamente ou quando você tem muitos ponteiros de função (retornos de chamada). Você apenas exclui o código dentro deles para que eles sejam chamados de qualquer maneira sem quebrar nada.