Quand les «fonctions statiques» entrent-elles en service?


25

OK, j'ai appris ce qu'est une fonction statique, mais je ne vois toujours pas pourquoi elles sont plus utiles que les fonctions membres privées. Cela pourrait être une sorte de nouvelle question ici, mais pourquoi ne pas remplacer à la place toutes les fonctions membres privées par des fonctions statiques?


1
Cela ne devrait-il pas être "remplacer toutes les fonctions statiques par des fonctions membres privées"? Actuellement, vous déclarez que vous ne voyez pas l'intérêt des méthodes statiques et continuez à demander pourquoi nous n'en utilisons pas plus.

5
Qu'est-ce qu'une "fonction statique"? En C ++, il y a au moins deux significations (et la dernière fois que j'ai examiné les brouillons C ++ 11, ils avaient supprimé l'avis de dépréciation staticpour limiter les fonctions à la portée du fichier.
David Thornley

Voulez-vous dire «fonction statique» dans le sens de fonction libre statique de portée de fichier en C / C ++, ou comme «fonction / méthode memenber statique»? C'est une énorme différence!
Jan Hudec

@JanHudec: Je pense qu'étant donné la présence de private membernous pouvons supposer en toute sécurité que l'OP pose des questions sur le concept OO et n'a aucune idée de la portée des fichiers statiques.
Matthieu M.

@MatthieuM: En fait, la présence de «membre privé» est exactement ce qui m'a amené à croire qu'il signifie des fonctions statiques au sens C ++. Parce que les fonctions statiques à portée de fichier et les fonctions membres privées sont les deux choses qui ont une utilisation très similaire en C ++, tout en remplaçant un membre statique public par un membre privé non statique n'a tout simplement pas beaucoup de sens. Malheureusement, OP ne semble pas répondre.
Jan Hudec

Réponses:


25

En supposant que vous utilisez la POO , utilisez des fonctions statiques lorsqu'elles ne dépendent d'aucun membre de la classe. Ils peuvent toujours être privés, mais de cette façon, ils sont optimisés car ils ne dépendent d'aucune instance de l'objet associé.

Autre que ce qui précède, je trouve les fonctions statiques utiles lorsque vous ne voulez pas créer une instance d'un objet juste pour y exécuter une fonction publique. C'est principalement le cas pour les classes auxiliaires qui contiennent des fonctions publiques pour effectuer un travail répétitif et général, mais n'ont pas besoin de maintenir un état entre les appels.


Merci Bernard. Btw, savez-vous ce que signifie pour un compilateur de "lier une méthode à la classe"?
Dark Templar

@ Dark Templar: Je ne peux pas dire que je le fais. Est-ce spécifique à une langue particulière?
Bernard

J'ai un léger problème avec votre définition "ils ne dépendent d'aucun membre de la classe". Les fonctions statiques des membres ne peuvent accéder à aucun membre non statique, mais elles peuvent accéder aux membres statiques. Les membres statiques sont des membres de la classe.
newprint

@newprint: Vous avez raison, mais ce n'est pas ce que j'ai dit. J'ai dit quand ils ne dépendent d'aucun membre de la classe. L'utilisation de membres statiques est correcte si nécessaire, mais ce n'est pas toujours le cas.
Bernard

8

Essayer une explication plus simplifiée que la précédente (assez bonne).

Un objet est normalement du code + des données. Une méthode statique est utilisée lorsque vous ne disposez que de la partie "code" (aucune donnée / état n'est conservé (sauf les membres de données statiques)).


5

Parce qu'ils ne nécessitent pas d'instance et peuvent être publics. Supposons que vous ayez besoin d'une fonction pour obtenir le plus grand dénominateur commun (GCD; très utile pour les classes de fractions; et oui, ce n'est qu'un exemple simple). Il est inutile de créer une classe d'objets dont le seul but est que vous puissiez avoir un thispointeur dont vous n'avez ni besoin ni utiliser gcd. Vous utilisez donc une méthode statique pour cela, idéalement sur la classe qui utilise réellement le GCD (par exemple dans la classe des fractions).

Bien sûr, s'il n'y a que des méthodes statiques, vous faites mal la POO et vous devez soit passer à la POO, soit utiliser un langage plus approprié à votre paradigme.


Ne serait-il pas préférable dans votre exemple d'utiliser une fonction gratuite?
Ela782

2
@ Ela782 Si la langue a des fonctions libres, oui.

D'accord, merci pour le réconfort. Je n'ai appris cette meilleure pratique que récemment. Cependant, j'ai actuellement du mal à voir quand une fonction membre statique publique pourrait réellement être utile, disons dans un langage comme C ++. Le cas d'utilisation pour les deux est lorsque la fonction ne dépend pas ou n'a pas besoin d'une instance de la classe, puis les fonctions libres sont la recommandation. Peut-être que cela devrait être une nouvelle question.
Ela782

1
@ Ela782 Oui, cela pourrait poser une belle question. Deux points rapides: en C ++ en particulier, les membres statiques sont utiles pour la méta-programmation de modèle car vous pouvez passer un type comme paramètre de modèle mais pas un espace de noms. En général, les fonctions statiques peuvent être utilisées pour indiquer que la fonction appartient vraiment étroitement à une classe, par opposition à appartenir simplement à un espace de noms (pensez stuff::Thing::Load(...)vs stuff::LoadThing()).

2

Je les utilise comme fonctions d'aide aux tâches courantes, par exemple:

  • Conversion des degrés en radians (et vice-versa);
  • Hachage d'une chaîne;
  • Conversion d'une énumération en autre chose (dans ce projet, je travaille, ils agissent comme une table de hachage);

La plupart de mes fichiers qui regroupent des fonctions statiques ont le suffixe Helper, ce qui signifie que c'est ce qu'ils font, m'aident à aller plus vite.


2

Quant à ce qu'est une méthode statique:

Les méthodes statiques ne nécessitent pas une instance de la classe et ne peuvent pas implicitement accéder aux données (ou à ceci, self, Me, etc.) d'une telle instance. [ 1 ]

Exemples de cas où les méthodes statiques sont utiles:

  • Méthodes globales / auxiliaires
  • Obtention des résultats d'une requête à partir d'une classe de modèle de données (appel d'un SP)

Utilisez-les uniquement le cas échéant.

  1. Si vous vous retrouvez à copier les mêmes méthodes dans plusieurs objets, envisagez de rendre la méthode statique afin de pouvoir suivre DRY.
  2. Utilisez des méthodes statiques si vous n'avez pas besoin d'une instance d'un objet (vous ne travaillez pas sur les variables d'instance de l'objet)

Si beaucoup de vos données sont en dehors des objets et qu'elles sont travaillées via des méthodes statiques, votre code n'est pas orienté objet et peut devenir difficile à maintenir.


1

Statique et privé sont en fait orthogonaux: une méthode peut être statique, ou privée, ou aucune, ou les deux.

Statique vs non statique (alias «méthodes d'instance») indique si la méthode fonctionne sur la classe elle-même (statique) ou sur une instance particulière (non statique). Selon la langue, vous pouvez appeler une méthode statique via une instance, mais vous ne pouvez jamais accéder à l'instance via une méthode statique (ce qui implique également que vous ne pouvez pas appeler de méthodes non statiques à l'intérieur d'une méthode statique, simplement parce que vous n'avez pas thisobjet). Utilisez des méthodes statiques pour implémenter un comportement qui est conceptuellement lié à la classe, mais qui ne se "lie" pas à une instance particulière. Un autre scénario dans lequel vous voudrez peut-être utiliser des méthodes statiques est lorsque vous avez une fonction qui opère sur deux instances d'une classe, et qu'aucun opérande ne mérite un statut privilégié - par exemple, en supposant que vous avez une classeVectoret vous souhaitez implémenter l'addition; votre méthode d'addition pourrait être appelée comme a.Add(b), mais est Vector.Add(a, b)probablement plus logique.

Privé vs public concerne la visibilité de la méthode. Les méthodes privées ne sont accessibles que depuis la portée de la classe, tandis que les méthodes publiques sont accessibles de n'importe où. L'utilisation la plus importante pour cela est l'encapsulation: en rendant publiques uniquement les méthodes et les propriétés dont le reste du code a absolument besoin pour communiquer avec votre classe, vous limitez les points auxquels le code extérieur peut introduire des problèmes et vous évitez les problèmes à l'intérieur votre classe de saigner dans le reste du projet.

Donc, règle générale:

  • rendre toutes les fonctions membres privées, sauf celles qui doivent être appelées de l'extérieur de la classe
  • faire toutes les méthodes méthodes d'instance, à moins qu'elles aient un sens même lorsqu'aucune instance de la classe n'existe

0

J'utilise des méthodes statiques en C ++ et C # pour les classes Utility, des classes qui n'ont pas de données d'instance, juste une façon de regrouper une collection de méthodes utiles et connexes.

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

0

En supposant que vous parlez de C ++ (vous ne l'avez pas dit) et que vous avez les bons termes (c'est-à-dire ne signifie pas les fonctions / méthodes membres):

Même une fonction membre privée doit encore être déclarée dans l'en-tête, ce qui signifie qu'elle fait réellement partie de l'API et de l'ABI de la classe, même si l'utilisateur ne peut pas réellement l'appeler. Si vous ajoutez, modifiez ou supprimez une fonction de membre privé, vous forcez la recompilation de toutes les classes dépendantes (l'en-tête a changé, make ne peut pas mieux le savoir) et lorsque vous le faites dans une bibliothèque, vous devez considérer la compatibilité de l'application en utilisant il.

D'un autre côté, les fonctions statiques à portée de fichier n'ont pas de symbole public, vous pouvez donc les ajouter, les modifier ou les supprimer à votre guise et rien au-delà de la seule unité de compilation ne sera jamais affecté.


0

En règle générale, vous avez besoin d'un principal statique pour servir de point d'entrée à votre programme. Cela pourrait être assez important.


0

Une fonction statique (et il existe différentes significations pour ce terme dans différentes langues), ne nécessite aucun état conservé entre les appels. Si elle est conceptuellement étroitement liée à ce qu'une classe fait, faites-en une fonction de classe (comme dans une classe et non un objet), ou sinon, faites-en une fonction globale (ou au niveau du module, peu importe). Il n'appartient pas à un objet s'il n'a pas besoin de l'état de l'objet.

Si vous lui passez tout le temps un état, ce n'est pas vraiment une fonction sans état, vous créez simplement une fonction avec état avec une syntaxe sans état. Dans ce cas, il appartient probablement à l'objet appelant, ou peut-être un refactoring pour mieux aligner l'état et le comportement est indiqué.


0

"pourquoi ne pas remplacer à la place toutes les fonctions membres privées par des fonctions statiques?"

... car un membre privé peut accéder aux données d'instance tout en lui permettant uniquement de se produire à partir d'appels effectués dans d'autres fonctions membres. La fonction statique peut être privée, mais elle ne pourra pas modifier ou faire référence à une instance de la classe à moins que l'instance ne soit transmise en tant que paramètre.


0

C'est drôle comme personne n'a encore pu donner une bonne réponse. Je ne suis pas sûr que ce soit le cas non plus. Vous devriez probablement le prendre comme un indice qu'ils devraient être utilisés le moins possible. Ils sont après tout procéduraux plutôt que POO.

Voici quelques exemples supplémentaires:

Dans Obj-C, où elles sont appelées méthodes de classe, elles sont couramment utilisées comme wrappers d'allocation où l'objet est placé dans le pool de comptage de références avant d'être renvoyé.

Un autre exemple d'Obj-C est d'enregistrer une nouvelle classe dans une collection de classes. Supposons que vous ayez un ensemble de classes traitant chacune un type de fichier. Lorsque vous créez une nouvelle classe pour un nouveau type de fichier, vous pouvez l'enregistrer dans la collection (une variable globale) à l'aide d'une méthode statique dans la classe qui détermine le type de fichier.

En C ++, une autre utilisation à laquelle je peux penser est de détecter doucement les erreurs. Votre fonction constructeur ne peut pas échouer, sauf en lançant une exception. Vous pouvez définir une variable d'instance d'erreur, mais ce n'est pas toujours approprié. Au lieu de cela, vous pouvez effectuer les parties qui pourraient échouer dans un wrapper statique, puis allouer et renvoyer le nouvel objet, ou NULL en cas d'échec.


0

Disons que vous voulez calculer le sinus de quelque chose.

Sans statique:

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

Avec statique:

double y = Math.sin(x)

Cela n'a aucun sens de rendre sinnon statique. Il est sans état et traite uniquement l'entrée.

Les fonctions statiques ne sont pas liées à des objets particuliers. Ce sont des fonctions "générales" indépendantes de l'état interne de l'objet.


Les méthodes statiques ne sont pas "garanties d'être apatrides". S'il est vrai qu'ils ne peuvent pas utiliser de données d'instance, ils ont également accès à un certain état (à savoir les membres statiques, à la fois de la classe à laquelle appartient la méthode statique et à d'autres états visibles globalement tels que les variables statiques d'autres classes).

@delnan: vrai ... vous avez raison. Permettez-moi de corriger cela maintenant.
dagnelies

Sans statique: x.sin(). Votre réponse suppose que le péché devrait être une fonction de "Math", alors qu'il opère clairement sur un double.
AjahnCharles

0

Un peu tard, mais j'aimerais essayer de créer une définition précise: les fonctions statiques sont des fonctions qui ne font pas ou ne peuvent pas référencer les propriétés / méthodes d'instance de la classe contenante.

Dans certains langages, comme C #, il peut y avoir des champs statiques ou des propriétés dans les classes statiques, il n'est donc pas tout à fait exact de dire qu'ils ne sont pas utilisés pour l'état; une fonction statique peut utiliser un état statique (global).

Fondamentalement, cela se résume à: les fonctions statiques, comme tout ce qui est statique, sont utiles quand il est logique qu'elles soient toujours disponibles sans dépendance sur les instances non statiques.

Les fonctions d'aide, comme les fonctions mathématiques, sont un exemple souvent cité, mais il en existe d'autres.

Si la classe que vous créez nécessite que les données soient immuables, il peut être judicieux de créer des fonctions statiques qui prennent une instance et transmettent une nouvelle instance car l'instance ne peut pas (ou ne devrait pas) être modifiée. Les classes de chaînes, par exemple, peuvent avoir des fonctions statiques qui acceptent une chaîne (ou 2 ou plus) et retransmettent une nouvelle chaîne.

Une autre raison pourrait être qu'il existe une classe qui conserve un état global ou des données d'une certaine sorte. Il peut y avoir des fonctions statiques qui fonctionnent avec les propriétés ou champs statiques de cette classe statique.


0

Je voudrais signaler une autre utilisation de statique f ().

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

Cela se résume à ceci: les staticfonctions vous permettent de créer des "constructeurs nommés", c'est-à-dire que vous nommez votre fonction statique avec un nom approprié et auto-documenté, et cette fonction statique appelle l'un des constructeurs (puisque les constructeurs ont des noms identiques, et vous pouvez avoir un beaucoup d’entre eux, il devient difficile de les distinguer).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.