Existem muitas razões pelas quais os globais são maus no POO.
Se o número ou tamanho dos objetos que precisam ser compartilhados for muito grande para ser transmitido com eficiência nos parâmetros de função, geralmente todos recomendam a Injeção de Dependências, em vez de um objeto global.
No entanto, no caso em que quase todo mundo precisa saber sobre uma determinada estrutura de dados, por que a Injeção de Dependência é melhor do que um objeto global?
Exemplo (simplificado, para mostrar o ponto em geral, sem se aprofundar muito em uma aplicação específica)
Existem vários veículos virtuais que possuem um grande número de propriedades e estados, de tipo, nome, cor, velocidade, posição etc. Vários usuários podem controlá-los remotamente e um grande número de eventos (ambos iniciado e automático) pode alterar muitos de seus estados ou propriedades.
A solução ingênua seria apenas criar um contêiner global deles, como
vector<Vehicle> vehicles;
que pode ser acessado de qualquer lugar.
A solução mais amigável ao OOP seria fazer com que o contêiner fosse membro da classe que lida com o loop do evento principal e instanciado em seu construtor. Toda classe que precisar, e for membro do thread principal, terá acesso ao contêiner por meio de um ponteiro em seu construtor. Por exemplo, se uma mensagem externa chegar por meio de uma conexão de rede, uma classe (uma para cada conexão) que manipula a análise assumirá o controle e o analisador terá acesso ao contêiner por meio de um ponteiro ou referência. Agora, se a mensagem analisada resultar em uma alteração em um elemento do contêiner ou exigir alguns dados dele para executar uma ação, ela poderá ser tratada sem a necessidade de passar milhares de variáveis por sinais e slots (ou pior, armazená-los no analisador para serem recuperados mais tarde por quem chamou o analisador). Obviamente, todas as classes que recebem acesso ao contêiner via injeção de dependência fazem parte do mesmo encadeamento. Threads diferentes não acessam diretamente, mas fazem seu trabalho e enviam sinais para o thread principal, e os slots no thread principal atualizam o contêiner.
No entanto, se a maioria das classes terá acesso ao contêiner, o que o torna realmente diferente de um global? Se tantas classes precisam dos dados no contêiner, a "maneira de injeção de dependência" não é apenas um global disfarçado?
Uma resposta seria a segurança do encadeamento: mesmo que eu tenha cuidado para não abusar do contêiner global, talvez outro desenvolvedor no futuro, sob pressão de um prazo próximo, use o contêiner global em um encadeamento diferente, sem cuidar de tudo os casos de colisão. No entanto, mesmo no caso de injeção de dependência, um poderia apontar para alguém executando em outro thread, levando aos mesmos problemas.