Quando as 'funções estáticas' entram em uso?


25

OK, eu aprendi o que é uma função estática, mas ainda não vejo por que elas são mais úteis que as funções de membro privadas. Isso pode ser uma pergunta nova aqui, mas por que não substituir todas as funções privadas de membros por funções estáticas?


11
Isso não deveria ser "substituir todas as funções estáticas por funções membro privadas"? Atualmente, você está afirmando que não entende o objetivo dos métodos estáticos e continua perguntando por que não usamos mais deles.

5
O que é uma "função estática"? Em C ++, há pelo menos dois significados (e última Olhei para C ++ 11 rascunhos, que eles tinham removido o aviso de reprovação para staticpara limitar funções para escopo do arquivo.
David Thornley

Você quer dizer "função estática" no sentido da função livre estática no escopo do arquivo em C / C ++ ou como "função / método estático do memenber"? É uma enorme diferença!
Jan Hudec

@JanHudec: Eu acho que, dada a presença de private membernós, podemos assumir com segurança que o OP está perguntando sobre o conceito de OO e não tem idéia sobre a estática do escopo do arquivo.
precisa

@ MatthieuM .: Na verdade, a presença de 'private member' é exatamente o que me leva a acreditar que ele significa funções estáticas no sentido C ++. Como funções estáticas com escopo no arquivo e funções de membro privadas são as duas coisas que têm uso muito semelhante em C ++, enquanto a substituição de membro estático público por membro não estático privado simplesmente não faz muito sentido. Infelizmente, o OP não parece estar respondendo.
Jan Hudec

Respostas:


25

Supondo que você esteja usando OOP , use funções estáticas quando elas não dependem de nenhum membro da classe. Eles ainda podem ser privados, mas dessa maneira são otimizados, pois não dependem de nenhuma instância do objeto relacionado.

Além do exposto, acho as funções estáticas úteis quando você não deseja criar uma instância de um objeto apenas para executar uma função pública. Esse é principalmente o caso das classes auxiliares que contêm funções públicas para realizar algum trabalho repetitivo e geral, mas não precisam manter nenhum estado entre as chamadas.


Obrigado Bernard. Btw, você sabe o que significa para um compilador "vincular um método à classe"?
Escuro Templar

@ Dark Templar: Não posso dizer que sim. Isso é específico para um idioma específico?
Bernard

Eu tenho um pequeno problema com a sua definição "eles não dependem de nenhum aluno". As funções estáticas de membro não podem acessar nenhum membro não estático; no entanto, eles podem acessar membros estáticos. Membros estáticos são membros da classe.
New

@ newprint: Você está correto, no entanto, não foi isso que eu disse. Eu disse quando eles não dependem de nenhum membro da classe. Usar membros estáticos é bom se necessário, mas nem sempre esse é o caso.
21413 Bernard

8

Tentando uma explicação mais simplificada do que a anterior (muito boas).

Um objeto é código + dados normalmente. Um método estático é usado quando você tem apenas a parte "código" para lidar (não há dados / estado sendo mantidos (exceto membros de dados estáticos)).


5

Porque eles não exigem uma instância e podem ser públicos. Digamos que você precise de uma função para obter o maior denominador comum (MDC; muito útil para classes de fração; e sim, este é apenas um exemplo simples). Não faz sentido criar uma classe de objetos cujo único objetivo é que você possa ter um thisponteiro do qual não precisa nem usa gcd. Então você usa um método estático para isso, idealmente na classe que realmente usa o GCD (por exemplo, na classe de fração).

Dos tribunais, se houver apenas métodos estáticos, você está fazendo OOP errado e deve mudar para realmente fazer OOP ou usar uma linguagem mais apropriada ao seu paradigma.


Não seria melhor no seu exemplo usar uma função livre?
Ela782

2
@ Ela782 Se o idioma tiver funções livres, sim.

Ok, obrigado pela garantia. Eu só aprendi essa melhor prática recentemente. No entanto, no momento estou tendo problemas para ver quando uma função de membro estática pública pode realmente ser útil, digamos em uma linguagem como C ++. O caso de uso para ambos é quando a função não depende ou precisa de uma instância da classe e, em seguida, funções livres são a recomendação. Talvez essa deva ser uma nova pergunta.
Ela782

11
@ Ela782 Sim, poderia fazer uma boa pergunta. Dois pontos rápidos: especificamente no C ++, os membros estáticos são úteis para a meta-programação de modelos, pois você pode passar um tipo como parâmetro de modelo, mas não como um espaço para nome. Em geral, funções estáticas podem ser usadas para indicar que a função realmente pertence a alguma classe, em vez de pertencer apenas a um espaço de nome (think stuff::Thing::Load(...)vs stuff::LoadThing()).

2

Eu os uso como funções auxiliares para tarefas comuns, sendo exemplos:

  • Converter graus em radianos (e vice-versa);
  • Hashing uma corda;
  • Convertendo de um enum para outra coisa (neste projeto, estou trabalhando, eles atuam como uma tabela de hash);

A maioria dos meus arquivos que agrupam funções estáticas tem o sufixo Helper, o que significa que é o que eles fazem, me ajuda a chegar a um lugar mais rápido.


2

Quanto ao que é um método estático:

Os métodos estáticos não requerem uma instância da classe nem podem acessar implicitamente os dados (ou isso, eu, eu etc.) dessa instância. [ 1 ]

Exemplos de quando os métodos estáticos são úteis:

  • Métodos globais / auxiliares
  • Obtendo resultados da consulta de uma classe Data Model (chamando um SP)

Apenas use-os sempre que apropriado.

  1. Se você estiver copiando os mesmos métodos em vários objetos, considere tornar o método estático para poder seguir DRY.
  2. Use métodos estáticos se você não precisar de uma instância de um objeto (você não está trabalhando com as variáveis ​​de instância do objeto)

Se muitos dos seus dados estão fora dos objetos e eles estão sendo trabalhados por métodos estáticos, seu código não é orientado a objetos e pode se tornar difícil de manter.


1

Estático e privado são de fato ortogonais: um método pode ser estático, ou privado, ou nenhum, ou ambos.

Estático versus não estático (também conhecido como 'métodos de instância') indica se o método opera na própria classe (estática) ou em uma instância específica (não estática). Dependendo do idioma, é possível chamar um método estático por meio de uma instância, mas nunca é possível acessar a instância por meio de um método estático (o que também implica que você não pode chamar métodos não estáticos de dentro de um método estático, simplesmente porque não possui thisobjeto). Use métodos estáticos para implementar um comportamento conceitualmente vinculado à classe, mas não 'vincule' a uma instância específica. Outro cenário em que você pode querer usar métodos estáticos é quando você tem uma função que opera em duas instâncias de uma classe e nenhum operando merece um status privilegiado - por exemplo, supondo que você tenha uma classeVectore você deseja implementar a adição; seu método de adição pode ser chamado como a.Add(b), mas Vector.Add(a, b)provavelmente faz mais sentido.

Privado x público são sobre visibilidade do método. Métodos particulares podem ser acessados ​​somente dentro do escopo da classe, enquanto métodos públicos são acessíveis de qualquer lugar. O uso mais importante para isso é o encapsulamento: tornando públicos apenas os métodos e propriedades absolutamente necessários para o restante do código se comunicar com sua classe, você limita os pontos nos quais o código externo pode apresentar problemas e evita problemas internos sua classe de sangrar para o resto do projeto.

Então, regra geral:

  • tornar todas as funções membro privadas, exceto aquelas que precisam ser chamadas de fora da classe
  • fazem todos os métodos métodos de instância, a menos que façam sentido, mesmo quando não existe nenhuma instância da classe

0

Uso métodos estáticos em C ++ e C # para classes Utility, classes que não possuem dados de instância, apenas uma maneira de agrupar uma coleção de métodos úteis e relacionados.

int count1 = DBUtil::GetCountOfSlackerEmployees();
int count2 = DBUtil::GetCountOfEmployedSlackers();

0

Supondo que você esteja falando de C ++ (você não disse) e que tenha os termos corretos (isto é, não significa funções / métodos membros):

Mesmo uma função de membro privada ainda precisa ser declarada no cabeçalho, o que significa que ela realmente se torna parte da API e da ABI da classe, mesmo que o usuário não possa chamá-la. Se você adicionar, modificar ou excluir uma função de membro privada, estará forçando a recompilação de todas as classes dependentes (o cabeçalho foi alterado, não é possível saber melhor) e, quando você faz isso em uma biblioteca, deve considerar a compatibilidade do aplicativo usando isto.

Por outro lado, as funções estáticas com escopo de arquivo não recebem um símbolo público; portanto, você pode adicioná-las, modificá-las ou excluí-las conforme desejar e nada além da única unidade de compilação será afetado.


0

Normalmente, você precisa de um main estático para atuar como um ponto de entrada para o seu programa. Isso pode ser meio importante.


0

Uma função estática (e há significados diferentes para esse termo em diferentes idiomas), não requer nenhum estado retido entre as chamadas. Se estiver conceitualmente intimamente ligada ao que uma classe faz, torne-a uma função de classe (como em uma classe que não é um objeto) ou, se não, faça-a uma função global (ou no nível do módulo, qualquer que seja). Não pertence a um objeto se não houver necessidade do estado do objeto.

Se você está passando um estado para ele o tempo todo, não é realmente uma função sem estado, você está apenas criando uma função com uma sintaxe sem estado. Nesse caso, provavelmente pertence ao objeto de chamada ou talvez seja indicada uma refatoração para melhor alinhar o estado e o comportamento.


0

"por que não substituir todas as funções privadas de membros por funções estáticas?"

... porque um membro privado pode acessar dados da instância, permitindo apenas que ocorra a partir de chamadas feitas dentro de outras funções de membro. A função estática pode ser privada, mas não poderá alterar ou se referir a uma instância da classe, a menos que a instância seja passada como parâmetro.


0

É engraçado como ninguém foi capaz de dar uma boa resposta ainda. Também não tenho certeza. Você provavelmente deve entender que eles devem ser usados ​​o menos possível. Afinal, eles são processuais e não OOP.

Aqui estão mais alguns exemplos:

No Obj-C, onde são chamados métodos de classe, são comumente usados ​​como invólucros de alocação, onde o objeto é colocado no pool de contagem de referência antes de ser retornado.

Outro exemplo do Obj-C é registrar uma nova classe em uma coleção de classes. Digamos que você tenha um conjunto de classes, cada uma manipulando um tipo de arquivo. Ao criar uma nova classe para um novo tipo de arquivo, você pode registrá-la na coleção (uma variável global) usando um método estático na classe que determina o tipo de arquivo.

Em C ++, outro uso em que consigo pensar é capturar erros suavemente. Sua função construtora não pode falhar, exceto lançando uma exceção. Você pode definir uma variável de instância de erro, mas isso nem sempre é apropriado. Em vez disso, você pode executar as partes que podem falhar em um invólucro estático e, em seguida, alocar e retornar o novo objeto, ou NULL na falha.


0

Digamos que você queira calcular o seio de alguma coisa.

Sem estática:

Math math = new Math()
double y = math.sin(x)

Com estática:

double y = Math.sin(x)

Não faz sentido tornar sinnão estático. É sem estado e apenas processa a entrada.

As funções estáticas não estão vinculadas a objetos específicos. São funções "gerais" que são independentes do estado interno do objeto.


Métodos estáticos não são "garantidos para serem apátridas". Embora seja verdade que eles não podem usar dados da instância, eles também têm acesso a algum estado (ou seja, membros estáticos, da classe à qual o método estático pertence e a outro estado globalmente visível, como as variáveis ​​estáticas de outras classes).

@ delnan: verdade ... você está certo. Deixe-me corrigir isso agora.
Dagnelies

Sem estática: x.sin(). Sua resposta pressupõe que o pecado deva ser uma função da "Matemática", enquanto está claramente operando em dobro.
AjahnCharles

0

Meio tarde aqui, mas eu gostaria de tentar criar uma definição precisa: funções estáticas são funções que não referenciam ou não podem fazer referência a propriedades / métodos de instância da classe que o contém.

Em alguns idiomas, como C #, pode haver campos ou propriedades estáticas nas classes estáticas, portanto, não é exatamente correto dizer que elas não são usadas para o estado; uma função estática pode fazer uso do estado estático (global).

Basicamente, tudo se resume a: funções estáticas, como qualquer coisa estática, são úteis quando faz sentido que elas sempre estejam disponíveis, sem dependência de instâncias não estáticas.

As funções auxiliares, como as funções matemáticas, são um exemplo frequente, mas existem outras.

Se a classe que você cria exigir que os dados sejam imutáveis, pode fazer sentido criar funções estáticas que recebem uma instância e passam uma nova instância, pois a instância não pode (ou não deve) ser alterada. As classes de string, por exemplo, podem ter funções estáticas que captam uma string (ou 2 ou mais) e devolvem uma nova string.

Outro motivo pode ser o fato de haver uma classe que mantém um estado global ou dados de algum tipo. Pode haver funções estáticas que funcionem com as propriedades ou campos estáticos dessa classe estática.


0

Gostaria de salientar outro uso da estática f ().

http://www.parashift.com/c++-faq/named-ctor-idiom.html

Tudo se resume a isso: staticfunções permitem criar "Construtores Nomeados", ou seja, você nomeia sua função estática com nome adequado e auto-documentável, e essa função estática chama um dos construtores (já que os construtores têm nomes idênticos e você pode ter um muitos deles, fica difícil distinguir entre eles).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.