Je travaille sur un projet C ++ dans lequel j'ai un tas de fonctions mathématiques que j'ai initialement écrites pour les utiliser dans le cadre d'un cours. En écrivant plus de code, cependant, j'ai réalisé que j'avais besoin de ces fonctions mathématiques partout.
Où est le meilleur endroit pour les mettre? Disons que j'ai ceci:
class A{
public:
int math_function1(int);
...
}
Et quand j'écris dans une autre classe, je ne peux pas (ou au moins je ne sais pas comment) l'utiliser math_function1
dans cette autre classe. De plus, j'ai réalisé que certaines de ces fonctions ne sont pas vraiment liées à la classe A. Elles semblaient en être au début, mais je peux maintenant voir à quel point elles ne sont que des fonctions mathématiques.
Quelle est la bonne pratique dans cette situation? En ce moment, je les ai copiées dans les nouvelles classes, ce qui, j'en suis sûr, est la pire pratique.
static
mot-clé?Réponses:
C ++ peut avoir des fonctions non-méthodes très bien, si elles n'appartiennent pas à une classe, ne les mettez pas dans une classe, mais placez-les simplement dans une portée globale ou dans un autre espace de noms
la source
math_function1(42)
peut appeler un membre de la classe actuelle;special_math_functions::math_function1(42)
appelle clairement une fonction indépendante). Cela étant dit,::math_function(42)
fournit la même homonymie.// optional
. Assaisonner selon les goûts.Cela dépend de la façon dont le projet est organisé et du type de modèle de conception que vous utilisez. En supposant qu'il s'agisse strictement d'un code utilitaire, vous disposez des options suivantes:
Notez que la première option sera la meilleure option et que les trois suivantes sont d'une utilité limitée. Cela dit, vous risquez peut-être de rencontrer des programmeurs C # ou Java effectuant certains travaux C ++ ou de travailler sur du code C # ou Java dans lequel l'utilisation de classes est obligatoire.
la source
Comme vous l'avez déjà dit, le copier-coller du code est la pire forme de réutilisation du code. Si vous avez des fonctions n'appartenant à aucune de vos classes ou pouvant être utilisées dans plusieurs scénarios, le meilleur endroit pour les placer serait une classe auxiliaire ou utilitaire. Si elles n'utilisent aucune donnée d'instance, elles peuvent être rendues statiques. Vous n'avez donc pas besoin de créer une instance de la classe d'utilitaire pour l'utiliser.
Voir ici pour une discussion des fonctions membres statiques en C ++ natif et ici pour les classes statiques en C ++ géré. Vous pouvez ensuite utiliser cette classe d’utilitaires partout où vous auriez collé votre code.
Dans .NET par exemple, des éléments tels que
Min()
etMax()
sont fournis en tant que membres statiques de laSystem.Math
classe .Si toutes vos fonctions sont liées aux mathématiques et que vous auriez autrement une
Math
classe gigantesque , vous voudrez peut-être la décomposer plus loin et avoir des classes commeTrigonometryUtilities
,EucledianGeometryUtilities
et ainsi de suite.Une autre option serait de placer une fonctionnalité partagée dans une classe de base des classes nécessitant ladite fonctionnalité. Cela fonctionne bien lorsque les fonctions en question doivent opérer sur des données d'instance. Cependant, cette approche est également moins flexible si vous souhaitez éviter les héritages multiples et ne vous en tenir qu'à une seule classe de base, car vous "utiliseriez" votre base unique. classe juste pour avoir accès à certaines fonctionnalités partagées.
la source
Désambiguïsez le terme "fonction d'assistance". Une définition est une fonction pratique que vous utilisez tout le temps pour faire votre travail. Ceux-ci peuvent vivre dans l'espace de noms principal et avoir leurs propres en-têtes, etc. L'autre définition de la fonction d'assistance est une fonction utilitaire pour une classe ou une famille de classes.
Now
isPrinter
est disponible pour tout code incluant son en-tête, maisprint_alignment_page
nécessite uneusing namespace printer_utils::Xerox;
directive. On peut aussi le référencer commeêtre plus clair.
La STL C ++ a un
std::
espace de noms qui couvre la quasi-totalité de ses classes et fonctions, mais il les divise catégoriquement en plus de 17 en-têtes différents pour permettre au codeur d'obtenir le nom de classe, le nom de fonction, etc. s'il souhaite écrire. les leurs.En fait, il n'est PAS recommandé d'utiliser
using namespace std;
dans un fichier d'en-tête ou, comme on le fait souvent, comme première ligne à l'intérieurmain()
.std::
est de 5 lettres et semble souvent une corvée à précéder de la fonction que l'on veut utiliser (surtoutstd::cout
etstd::endl
!), mais cela sert à quelque chose.Le nouveau C ++ 11 contient des sous-espaces de noms pour des services spéciaux tels que
qui peut être amené à être utilisé.
Une technique utile est la composition d'espace de noms . On définit un espace de noms personnalisé pour contenir les espaces de noms dont vous avez besoin pour votre
.cpp
fichier particulier et les utiliser à la place d'un ensemble d'using
instructions pour chaque élément d'un espace de noms dont vous pourriez avoir besoin.Cette technique limite l'exposition à l'ensemble
std:: namespace
( c'est grand! ) Et permet d'écrire un code plus propre pour les lignes de code les plus courantes écrites par les utilisateurs.la source
Vous voudrez peut-être l'insérer dans une fonction de modèle afin de le rendre disponible pour différents types d'entiers et / ou de flottants:
Vous pouvez également créer des types personnalisés ordonnés qui représentent, par exemple, des nombres énormes ou des nombres complexes en surchargeant les opérateurs pertinents pour votre type personnalisé afin de les rendre compatibles avec les modèles.
la source