Qual é a diferença entre funções de amigo e funções estáticas em c ++?

São duas espécies completamente diferentes. Funções estáticas são funções que são membros da classe, mas não de uma instância. As variáveis ​​de membro estático estão disponíveis e instanciadas ao seu valor inicial após a classe ser carregada do código do objeto. Métodos / funções estáticas não precisam ter uma instância da classe para serem executados. Por exemplo:

  1. classe VehicleFactory {public: static Vehicle buildFord (const std :: string & sModel); Veículo estático buildToyota (const std :: string & sModel); Veículo estático buildKia (const std :: string & sModel); // ...};

Agora você pode chamar isso:

  1. VehicleFactory.buildToyota ("Prius");

e você não precisa criar um objeto Vehicle Factory como este:

  1. VehicleFactory objFactory;

De fato, é aconselhável que não. Se você fez isso:

  1. objFactory.buildKia ("Rio");

Muitos compiladores C ++ enviariam um aviso sobre isso porque é uma função estática.

As funções de amigo, por outro lado, não têm nada a ver com métodos estáticos ou de instância. Não tenho certeza se as funções de amigo podem ser estáticas, mas verifique isso. Eu apenas os usei apenas como funções regulares. Eles só têm a ver com controle de acesso. Por exemplo, digamos que você tenha uma classe com métodos e variáveis ​​privados e / ou protegidos, como deveria. Você pode querer alguma função / método para acessá-los. O exemplo que vem à mente é um operador sobrecarregado. Veja aqui:

  1. classe String {private char * mStr; muiLength privado não assinado; public String (); // ... outros construtores, destruidores e / ou funções friend String & operator + (const String & objString1, const String & objString2);}; String & operator + (const String & objString1, const String & objString2) {char * strReturn; não assinado uiNewLength = objString1.muiLength + objString2.muiLength; strReturn = novo caractere [uiNewLength + 1]; strcpy (strReturn, objString1.mStr); strcat (strReturn, objString2.mStr); return (new String (strReturn, uiNewLength));}

A definição da função operador sobrecarregado + aproveita as variáveis ​​privadas mStr e muiLength; Certamente, deveria ter tirado vantagem de outras funções, como getLength e talvez um operador de elenco sobrecarregado de char *, que seria público. As funções de amigo geralmente são denunciadas de forma inadequada, pois existem maneiras melhores de realizar o trabalho sem chamar as funções de amigo.

"Funções de amigo" não são realmente uma

coisa

em C ++. Ah, claro que você pode ter um

amigo

declaração de função (ou mesmo

definição

), mas isso torna a função declarada um amigo de um tipo de classe, não uma "função de amigo". Em outras palavras, “amigo” é propriedade de uma declaração, não de uma função (ou outra entidade, nesse caso).

Em particular, qualquer função pode ser uma função de amigo: Membro ou não membro, modelo ou nenhum modelo, etc., quando declarada como função de amigo em uma classe X, uma função (ou função de membro) obtém acesso a membros privados, assim como um membro de essa classe.

"Funções estáticas" é um termo levemente ambíguo em C ++ (talvez não seja surpreendente, pois a palavra-chave

estático

está sobrecarregado de várias maneiras em C ++). Por exemplo:

  1. estático vazio f ();

declara uma "função estática", que é uma função de espaço para nome com ligação interna (distinta de funções semelhantes em outras unidades de tradução).

Eu

pensar

, no entanto, você pretendia escrever "estática

membro

função". Essas são funções de membro de uma classe não associada a nenhuma instância específica dessa classe. Eles são assim

compartilhado

por todas as instâncias do objeto de classe, assim como uma variável local estática é compartilhada entre todas as chamadas da função em que aparece:

  1. struct X {estático vazio f (); // Compartilhado entre todos} x; // X objects.void g () {static int x; // Compartilhado entre todas as chamadas} // de g ().

Como um membro estático é um membro, ele pode ser referido usando a notação de membro; por exemplo, "

xf ()

”Com o exemplo acima. No entanto, isso não implica

isto

valor porque não está associado a nenhum objeto em particular. Em vez disso, ele está associado à própria classe e, portanto, você também pode chamá-lo com uma notação como "

X :: f ()

”.