Índice:

Como fazer o Singleton Design Pattern em C ++: 9 etapas
Como fazer o Singleton Design Pattern em C ++: 9 etapas

Vídeo: Como fazer o Singleton Design Pattern em C ++: 9 etapas

Vídeo: Como fazer o Singleton Design Pattern em C ++: 9 etapas
Vídeo: Singleton Design Pattern in C# - Do it THAT way 2024, Junho
Anonim
Como fazer o Singleton Design Pattern em C ++
Como fazer o Singleton Design Pattern em C ++

Introdução:

O objetivo deste guia de instruções é ensinar ao usuário como implementar o padrão de design singleton em seu programa C ++. Ao fazer isso, este conjunto de instruções também explicará ao leitor por que os elementos de um singleton são como são e como o código é processado. Saber disso ajudará no futuro a depurar seus singletons futuros. Qual é o padrão de design singleton? O padrão de design singleton é um padrão de design onde o codificador cria uma classe que só pode ser instanciada uma vez, as funções públicas das classes podem ser acessadas basicamente em qualquer lugar, desde que você tenha #incluído o arquivo de cabeçalho em outros arquivos relacionados ao projeto.

O padrão de projeto singleton é um padrão de projeto obrigatório para qualquer programador orientado a objetos, programadores de software e programadores de jogos. O padrão de design singleton também é um dos padrões de design de codificação mais fáceis que existem. Aprendê-lo pode ajudá-lo a aprender outros padrões de projeto mais difíceis no futuro. Também pode ajudá-lo a otimizar o código do seu programa de maneiras que você não achava possível.

Embora a dificuldade do padrão de projeto singleton seja fácil quando comparado a outros padrões de projeto, este conjunto de instruções tem uma dificuldade média. Isso significa que, para seguir essas instruções, recomendamos que você conheça os requisitos básicos e avançados de sintaxe do C ++. Você também deve conhecer a etiqueta adequada de codificação C ++ (ou seja, manter as variáveis de classe privadas, uma classe por arquivo de cabeçalho, etc.). Você também deve saber como liberar memória e como os construtores e destruidores funcionam em C ++.

Este guia de instruções levará em média cerca de 10-15 minutos.

Requisitos de material:

- Um computador (pode ser PC ou Mac) capaz de executar o Visual Studios (qualquer versão)

-Um programa simples, criado no Visual Studios, com o qual você pode testar seu singleton

Nota: O padrão de design singleton pode ser feito em qualquer outro IDE de suporte C ++ ou interface de codificação, mas para este conjunto de instruções, usaremos o Visual Studios Enterprise Edition.

Etapa 1: Crie sua aula, com arquivo de cabeçalho e arquivo CPP

Crie sua aula, com arquivo de cabeçalho e arquivo CPP
Crie sua aula, com arquivo de cabeçalho e arquivo CPP
Crie sua aula, com arquivo de cabeçalho e arquivo CPP
Crie sua aula, com arquivo de cabeçalho e arquivo CPP

Para criar esses dois arquivos e a classe de uma vez, abra seu projeto / programa no Visual Studios, vá até o explorador de soluções, clique com o botão direito e uma caixa deverá aparecer perto do cursor do mouse, encontre a opção “Adicionar”, passe o mouse sobre ele, e outra caixa deve aparecer à direita. Nesta caixa, você deseja encontrar a opção “Novo Item..”, clique nela e deverá aparecer uma janela semelhante à da foto 1.1 abaixo. Nesta janela você deseja selecionar “Classe C ++” e então clicar em “Adicionar”. Isso abrirá outra janela semelhante à imagem da foto 1.2. Nesta janela, você digita o nome da sua turma no campo “Nome da turma” e o Visual Studios nomeará automaticamente o arquivo real após o nome da turma. Para o propósito desta instrução, vamos nomear nossa classe "EngineDebugSingleton", mas pode ser qualquer nome baseado em letras. Agora você pode clicar em “OK” e prosseguir para a etapa 2.

Nota: O explorador de soluções e onde os arquivos são mantidos em seu computador são separados. Mover ou criar qualquer coisa no gerenciador de soluções não moverá ou organizará os arquivos no gerenciador de arquivos do sistema operacional. Uma maneira segura de organizar seus arquivos no gerenciador de arquivos seria remover, mas não excluir os arquivos específicos do gerenciador de soluções, mover os mesmos arquivos no gerenciador de arquivos para o local desejado e, em seguida, voltar ao gerenciador de soluções, clique com o botão direito, encontre a opção “Adicionar”, então encontre “Item Existente” e encontre os arquivos que você moveu. Certifique-se de mover o cabeçalho e o arquivo cpp.

Etapa 2: definir o construtor como privado

Defina o construtor como privado
Defina o construtor como privado

Com o arquivo CPP recém-criado e o arquivo de cabeçalho, se ele não abriu automaticamente quando você o criou, vá para o gerenciador de soluções e clique e abra o “EngineDebugSingleton.h”. Você então será saudado com um “EngineDebugSingleton ()”, o construtor padrão da classe e “~ EngineDebugSingleton ()” o destruidor da classe. Para esta etapa, queremos definir o construtor como privado, isso significa que essa função está disponível apenas para a classe e nada mais. Com isso, você não será capaz de criar uma variável ou alocar a classe para a memória fora da classe, apenas no arquivo de cabeçalho das classes e nas outras funções das classes. Ter o construtor privado é a chave para o padrão de design e como os singletons operam. Descobriremos em etapas futuras como um singleton é instanciado e acessado.

A classe deve ficar assim depois de mover o construtor para privado (veja a foto associada)

Etapa 3: definir o destruidor como privado

Defina o destruidor como privado
Defina o destruidor como privado

Como fizemos com o construtor em

etapa 2, para esta etapa, vamos agora definir o destruidor como privado. Como com o construtor, nada, exceto a própria classe, será capaz de deletar quaisquer variáveis da classe da memória.

A classe agora deve ficar assim depois de concluir esta etapa. (Veja a foto associada)

Etapa 4: Criação de uma variável de ponteiro estático no singleton

Criando uma variável de ponteiro estático no singleton
Criando uma variável de ponteiro estático no singleton

Nesta etapa, criaremos um

variável de ponteiro estático do tipo “EngineDebugSingleton *”. Esta será a variável que será usada para alocar nosso singleton na memória e apontará para ela durante todo o tempo em que nosso singleton estiver alocado na memória.

É assim que nosso arquivo de cabeçalho deve ficar depois de criar esta variável

Etapa 5: Criação de uma função de instância

Criação de uma função de instância
Criação de uma função de instância

Agora queremos fazer uma instância

função. A função precisará ser estática e retornará uma referência à nossa classe (“EngineDebugSingleton &”). Chamamos nossa função de Instance (). Na função em si, queremos primeiro testar se ptrInstance == nullptr (pode ser abreviado para! PtrInstance), se for nullptr, isso significa que o singleton não foi alocado e no escopo da instrução if, deseja alocar executando ptrInstance = new EngineDebugSingleton (). É aqui que você realmente aloca o singleton na memória. Depois de sair do escopo da instrução if, retornaremos então para onde ptrInstance está apontando, o que é denotado pela sintaxe “* ptrInstance”. Estaremos usando essa função intensamente ao fazer nossas funções públicas estáticas, para que possamos verificar se o singleton foi criado e alocado para a memória. Em essência, essa função faz com que você possa ter apenas uma alocação da classe e não mais.

Esta é a aparência de nossa classe agora, após criar a função Instance (). Como você pode ver, tudo o que fizemos ficou na seção privada da aula, isso vai mudar um pouco nas próximas etapas.

Etapa 6: Criação de funções públicas estáticas

Criação de funções públicas estáticas
Criação de funções públicas estáticas
Criação de funções públicas estáticas
Criação de funções públicas estáticas
Criação de funções públicas estáticas
Criação de funções públicas estáticas

Depois de fazer a função de

etapa 5, você pode começar a criar funções públicas estáticas. Cada função pública deve ter uma função privada para acompanhá-la, o nome desta função não pode ser o mesmo. Por que tornar a função estática? Estamos tornando as funções públicas estáticas para que possam ser acessadas sem um objeto real. Então, em vez de fazer algo como “EngineDebugSingleObj-> SomeFunction ()”, fazemos “EngineDebugSingleton:: Some Function ()”. Isso possibilita que um singleton seja acessado basicamente em qualquer lugar do código, desde que você tenha #incluído o arquivo de cabeçalho no arquivo de projeto específico com o qual está trabalhando. Com isso, você também pode criar o singleton por meio de qualquer uma de suas funções públicas.

Para nossos propósitos nesta etapa, criamos duas funções void estáticas públicas, “add ()” e “subtract ()”. Na seção privada, temos mais duas funções, “PrivAdd ()” e “PrivSubtract ()”. Também adicionamos uma variável interna chamada “NumberOfThings”. A definição dessas funções irá para o arquivo CPP de nossas classes. Para fazer com que a função entre facilmente no arquivo CPP, você destaca, com seu cursor, a função, que deve ter uma linha verde abaixo dela, e pressiona “ALT ESQUERDA + ENTER”, isso lhe dará a opção de criar a definição no arquivo CPP associado às classes. Veja a Foto 6.1 para ver como o arquivo de cabeçalho deve se parecer e depois de criar todas as definições de função, seu CPP deve se parecer com a Foto 6.2, exceto que suas definições de função não terão nenhum código nelas.

Agora você desejará adicionar o mesmo código da Foto 6.2 em suas definições de função. Conforme declarado anteriormente, nossas funções públicas farão uso da função Instance (), que retornará o que ptrInstance está apontando. Isso nos permite acessar as funções privadas de nossa classe. Com qualquer função pública de singleton, você só deve chamar essa função de instância. A única exceção a isso é nossa função Terminate.

Nota: As funções públicas e privadas exatas mostradas nesta etapa não são necessárias, você pode ter diferentes nomes de função e operações na função privada, mas para qualquer tipo de função pública, você deve ter uma função privada para acompanhá-la e a função pública deve sempre usar, em nosso caso, a função Instance ().

Etapa 7: Criando a função de encerramento

Criando a Função Terminate
Criando a Função Terminate
Criando a Função Terminate
Criando a Função Terminate

Como só podemos desalocar nosso singleton da memória em nossa classe, devemos criar uma função pública estática. Esta função irá chamar delete em ptrInstance, que chama o destruidor de classe e então vamos querer definir ptrInstance de volta para nullptr para que ele possa ser alocado novamente se seu programa não terminar. Você também vai querer encerrar seus Singletons para limpar qualquer memória alocada que tenha alocado em qualquer variável privada de Singleton.

Etapa 8: Configurando PtrInstance para Nullptr

Configurando PtrInstance para Nullptr
Configurando PtrInstance para Nullptr

Para completar seu singleton, você deseja acessar o arquivo EngineDebugSingleton. CPP e, na parte superior do arquivo CPP, em nossa instância, digite “EngineDebugSingleton * EngineDebugSingleton:: ptrInstance = nullptr.”

Fazer isso inicialmente definirá ptrInstance como nullptr, portanto, quando você passar pela função de instância pela primeira vez, nossa classe poderá ser alocada na memória. Sem ele, você provavelmente obterá um erro, porque estará tentando acessar uma memória que não tem nada alocado para ela.

Etapa 9: Teste e Conclusão

Teste e Conclusão
Teste e Conclusão

Agora vamos querer testar se nosso singleton para ter certeza de que funciona. Isso nos envolverá chamando as funções públicas conforme descrito na etapa 6 e recomendamos que você configure pontos de interrupção para percorrer seu código e ver se o singleton está funcionando como deveria ser. Nosso ponto de partida será o main.cpp do nosso projeto e nosso main.cpp agora se parece com a imagem abaixo.

Parabéns! Você acabou de concluir sua primeira implementação do Singleton Design Pattern. Com esse padrão de design, agora você pode otimizar seu código de várias maneiras. Por exemplo, agora você pode fazer sistemas gerenciadores que operam em todo o tempo de execução do seu programa, que podem ser acessados por meio de funções estáticas em qualquer lugar onde você incluiu a classe.

Seu arquivo de cabeçalho final deve ser semelhante à foto 7.1. O arquivo CPP associado ao seu singleton deve ser semelhante à Foto 6.2 com a adição, na parte superior do arquivo, do código mostrado na etapa 8. Esta instrução forneceu a você uma estrutura simples do Singleton Design Pattern.

Conselhos para resolução de problemas:

Obtendo erros relacionados à memória?

Certifique-se de consultar as etapas 7 e 8 para certificar-se de que está configurando ptrInstance como nullptr.

Loop infinito ocorrendo?

Certifique-se de que para as funções públicas, em suas definições, você está chamando a função privada, não a mesma função pública.

Objetos alocados dentro do singleton causando vazamentos de memória?

Certifique-se de chamar a função de término do seu singleton quando apropriado dentro do código do seu programa, e no destruidor do seu singleton, certifique-se de desalocar quaisquer objetos que foram alocados para a memória dentro do escopo do código do singleton.