10
votes

Statique Const double en C ++

Est-ce la bonne façon d'utiliser une variable de const statique? Dans ma classe de niveau supérieur (forme) xxx

puis plus tard dans une classe qui s'étend de la forme, j'utilise la forme :: pi. Je reçois une erreur de liaison. J'ai déplacé la double forme de const :: pi = 3.14 ... au fichier de forme.cpp et mon programme compile ensuite. Pourquoi cela se passe-t-il? merci.


0 commentaires

7 Réponses :


11
votes

parce que const double forme :: pi = 3.14159265; est la définition de forme :: pi et c ++ permet uniquement à une seule définition d'un symbole (appelé règle d'une définition que vous pouvez voir dans sa forme acronyme ODR). Lorsque la définition est dans le fichier d'en-tête, chaque unité de traduction obtient sa propre définition qui enfreint cette règle.

en le déplaçant dans le fichier source, vous obtenez seulement une seule définition.


1 commentaires

J'ai le même problème. Le problème est que, si cette bibliothèque, et je veux que mon utilisateur voie la valeur de la forme :: pi dans le fichier .h, mais pas le contenu du CPP (I.e, une autre définition de fonction). Que dois-je faire?



3
votes

Cela arrive parce que vous ne pouvez pas définir la forme :: PI plus d'une fois. Il est défini une fois lorsque vous incluez la forme.h dans la forme.Cpp, puis à nouveau de chaque autre fois que vous utilisez la forme.h dans un autre fichier CPP. Lorsque vous allez vous lier, vous programmez ensemble le lien de lien de barf à cause de plusieurs définitions.


0 commentaires

1
votes

La ligne Const double forme :: pi = 3.14159265; doit être dans votre fichier de forme.cpp. Le fichier d'en-tête est de déclarer les variables. Vous ne pouvez définir qu'une variable une fois, elle doit donc être effectuée dans le .cpp . Le fichier d'en-tête indique comment utiliser ces variables et ces fonctions, le fichier CPP indique quoi faire.


0 commentaires

12
votes

Les éléments de données de point flottant statiques doivent être définis et initialisés dans un fichier source. La règle d'une définition interdit une définition extérieure à la classe Classe {} dans l'en-tête, et seuls les éléments de données intégrés sont autorisés à être initialisés à l'intérieur du bloc Classe {} Block. < P> Ceci est également regrettable car, être une valeur algébrique, la valeur immédiate à la main pourrait être agréable pour l'optimisation, plutôt que de se charger d'une variable globale. (La différence est susceptible d'être sans conséquence, cependant.)

Il y a une solution, cependant! xxx

définitions de fonction inline, y compris les données statiques, y compris autorisé à l'intérieur de la classe {} bloc.

aussi, je vous recommande d'utiliser m_pi à partir de , qui Vous devriez également obtenir de .


7 commentaires

De plus: les modèles ont une liaison différente, vous pouvez donc utiliser un modèle pour rendre la définition visible.


@Justin: Je ne pense pas que le modèle vous obtient quoi que ce soit ici, sauf complication supplémentaire.


Un modèle peut compliquer les choses, mais cela vous achète potentiellement une exception à la règle d'une définition pour "Membre de données statique d'un modèle de classe" (parmi d'autres exceptions ODR). Voir 3.2 / 5 et 14.5.1.3 de la norme C ++.


@Michael: Mais identifier ce membre de données de modèle en usage nécessite une liste d'arguments de modèle, qui n'est pas moins fastidieuse (et un peu moins clair) qu'un appel de la fonction.


+1 pour la solution (que je déclare explicitement comme en ligne )


M_PI est pratique, mais cela ne fait pas partie de la norme C ++.


@Quant_Dev en effet, cela fait partie de POSIX. En pratique, cependant, de nombreuses plates-formes non POSIX le fourniront aussi.



0
votes

Pour les types de données primitifs (comme Int, double mais pas caractère []), vous pouvez également définir la constante dans la définition de la classe dans le fichier d'en-tête, par exemple:

class Shape
{
public:
    static const double pi = 3.14159265;

private:
    double originX;
    double originY;
};


2 commentaires

Vous ne pouvez faire que cela pour des types d'intégrale et d'énorme. Les types de points flottants ne sont pas autorisés.


@Dennis: Oups! Vous avez raison! J'ai été duper par le compilateur (GCC et ICC ont permis à Static Cons Double Double d'être initialisé dans la classe) ...



12
votes

Si vous avez un moyen d'ajouter C ++ 11 code> (ou ultérieur) Drapeau de votre compilateur, vous auriez pu faire:

ifndef SHAPE_H
#define SHAPE_H

class Shape
{
public:

    static constexpr double pi = 3.14159265;
private:
    double originX;
    double originY;
};

#endif


2 commentaires

Bonjour, selon en.cpprefreence.com/w/cpp/language/CONSTEXPR Constexpr est introduit dans C ++ 11, par conséquent, le drapeau du compilateur doit-il être C ++ 11,14,17 ou 20 mais surtout pas "C ++ 0x"?


Ma réponse a déjà 8 ans. Il n'y avait pas de C ++ 17 cette fois-ci. Vous êtes libre de modifier la réponse cependant.



0
votes

Implémentez une fonction qui renvoie l'index d'une valeur à la liste s'il existe. Sinon, retour -1 s'il n'y a pas de valeur. Si la même valeur existe plusieurs fois sur la liste, la première valeur est supprimée du bas.

public static intfindFromLast (List <Double> l, double value ) {///…}


0 commentaires