J'écris une bibliothèque d'algèbre linéaire (histoire courte, c'est un devoir d'école) qui implique des matrices, des vecteurs, etc. Dans le processus de création de cette bibliothèque, je vais créer des fonctions qui effectuent des opérations mathématiques sur des objets. Par exemple, transposer la matrice, inverser la matrice, normaliser le vecteur, etc.
J'étais curieux de savoir quelle était la "meilleure pratique" pour ce type de fonction ... Autrement dit, devrais-je faire de la fonction une fonction membre ou non membre? (Par souci de clarté / utilisation de la bibliothèque)
Exemple:
//Member function way:
B = A.transpose();
C = A.inverse();
//Non-member function way:
B = linalg::transpose(A); //Non-member transpose function in linear algebra namespace
C = linalg::inverse(A);
Existe-t-il une norme concernant ce type d'opérations? Ou, au moins, y a-t-il une façon courante pour les gens de faire cela? Je penche vers la première option, mais j'aimerais savoir si cela est recommandé.
Les fonctions membres et non membres ont de réels avantages en plus du simple goût. Par exemple, les tableaux sous-jacents utilisés pour implémenter une
matrix
classe seront probablementprivate
, par conséquent, vous devrez utiliser àfriend
moins que vous n'utilisiez des fonctions membres. À cet égard, une conception OO peut être meilleure.Cependant, gardez à l'esprit que, de temps en temps, les informaticiens doivent mettre en œuvre une formule mathématique complexe sans toujours savoir ce que vous faites réellement. Quand je dois le faire, je préfère les fonctions non membres car le résultat "visuel" sera plus proche de la formule mathématique d'origine (puisque la formule mathématique utilise généralement un style fonctionnel).
Au final, la réponse est la même que celle de Doc Brown: c'est une question de goût. En bref, vous pourriez envisager d'écrire une bibliothèque de style OO avec des fonctions membres (plus facile à écrire, non
friend
), puis d'écrire des fonctions non membres pour effectuer les mêmes tâches qui transmettront simplement leurs arguments aux membres. Il vous permet d'être cohérent et de laisser l'utilisateur choisir ce qu'il pense être le mieux.la source
Si vous approfondissez votre énoncé de problème, il est clair qu'à un moment donné, vous utiliserez des structures de données personnalisées qui représentent certaines entités mathématiques. Par exemple, vous pourriez représenter une matrice mes moyens d'un tableau à n dimensions. Pour développer votre exemple,
(L'exemple C ++ est simplifié, vous pouvez utiliser des modèles et autres.)
Le point à considérer est la facilité d'utilisation des structures de données personnalisées dans les deux cas. Le C ++ (ou tout objet orienté) en tant que langage est plus puissant en soi, et cela s'étend au consommateur de la bibliothèque autant qu'il profite à l'implémenteur. J'ai utilisé des bibliothèques C uniquement dans le passé et ces structures de données personnalisées semblent se répandre partout en un rien de temps! Alors que l'interopérabilité est plus facile à réaliser avec ces derniers (à l'aide de constructeurs spéciaux, peut-être?)
Pour finir, si vous utilisez C ++, une approche orientée objet est définitivement recommandée.
la source
transpose
exemples. La raison principale pour laquelle C ++ est plus facile est que la sémantique de copie et d'affectation fonctionne réellement.A = B
peut compiler en C mais fait probablement la mauvaise chose.