Question

Je travaille en C ++ et j'ai besoin de savoir si une valeur scalaire (par exemple un double) est " " ou pas. J'ai aussi besoin de pouvoir & "; Undef &"; le cas échéant:

class Foo {
public:
    double get_bar();

private:
    double bar;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( undefined(bar) )
        calculate_bar();
    return bar;
}

Est-ce possible en C ++?

Merci

Était-ce utile?

La solution

Comme l’indiquent les autres réponses, C ++ n’a pas ce concept. Vous pouvez cependant facilement y remédier.

Vous pouvez également avoir une valeur indéfinie à laquelle vous initialisez la barre dans le constructeur, généralement -1,0 ou quelque chose de similaire.

Si vous savez que Calculate_bar ne renvoie jamais de valeurs négatives, vous pouvez implémenter la fonction non définie en vérifiant < 0.0.

Une solution plus générale consiste à avoir une valeur booléenne indiquant si la barre est définie mais que vous avez initialisé à false dans le constructeur et que vous la définissez pour la première fois. boost :: optional le fait dans une manière élégante basée sur des modèles.

Voici à quoi ressemblerait votre exemple de code.

class Foo {
public:
    double get_bar();
    Foo() : barDefined(false) {}
private:
    double bar;
    bool barDefined;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( barDefined == false ) {
        calculate_bar();
        barDefined = true;
    }
    return bar;
}

Autres conseils

Comme d'autres l'ont fait remarquer, rien ne ressemble à un & "non défini &"; Etat. Mais vous voudrez peut-être examiner boost.optional

Si vous voulez dire au moment de l'exécution, cela n'existe pas. Si bar n'est jamais initialisé, tous les bits aléatoires seront conservés, en fonction de la façon dont l'objet est alloué (certains allocateurs initialiseront la nouvelle mémoire à zéro).

edit: il appartient au programmeur de gérer l'état de l'objet dans les constructeurs et / ou les méthodes d'initialisation manuelles telles que init()

Pourquoi ne pas conserver un indicateur distinct initialisé à false puis à true lorsque la barre est calculée. Il peut ensuite être annulé en définissant à nouveau le drapeau sur false.

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;

C ++ n'a pas de " indéfini " Etat pour les types primitifs. Le plus proche disponible pour float / double serait NAN, mais sa signification est vraiment différente.

Cela n’est pas possible en C / C ++, les primitives attribueront toujours une valeur (principalement des déchets, quel que soit ce qui était à cet endroit en mémoire avant, sauf s’il est explicitement attribué lors de la déclaration). Il est courant que j’ai une valeur de marque de réservation (c’est-à-dire 0 pour les pointeurs) qui indique non utilisée, mais elles doivent également être explicitement affectées. Si votre double peut prendre n'importe quelle valeur, alors je vous suggère de mettre un booléen à côté, attribué à false initialement, et de tester / définir celui-ci lorsque vous souhaitez effectuer votre calcul.

Vous devez le faire en utilisant un booléen supplémentaire.

Pour implémenter l'utilisation d'un booléen supplémentaire, vous pouvez essayer une logique semblable au modèle suivant:

template<typename T>
struct Defined
{
 bool defined;
 T value;
 Defined() : defined(false) {}
 Defined(const T& value_) : defined(true), value(value_) {}
 ... and perhaps other operators here ...
 ... to make this behave even more like a T ...
};

Vous pouvez essayer le Construire lors de la première utilisation idiome et écrivez get_bar() de cette façon:

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

Lorsque vous appelez bar, cela fera double & pour vous si personne ne l’a encore demandé. Tous les appels ultérieurs renverront simplement <=>. Comme l'indique la page liée, cette mémoire ne fuit pas techniquement car le système d'exploitation la récupérera à la fermeture du programme.

MISE À JOUR:

Changement de la valeur de retour en <=> pour vous permettre de modifier <=>.

Initialisez bar à une valeur qui ne peut jamais se produire lorsque vous appelez la fonction something() dans le constructeur.

Par exemple:

Foo(): bar(-1)
{
}

Recherchez ensuite la valeur -1 dans la get_bar fonction.

(hmmm Laserallan a également posté cette réponse 1 minute avant :-( ;-))

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top