C ++ où initialiser statique const

130

j'ai un cours

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

Où est le meilleur endroit pour initialiser la chaîne sdans le fichier source?

Thomas
la source

Réponses:

178

N'importe où dans une unité de compilation (généralement un fichier .cpp) ferait:

foo.h

class foo {
    static const string s; // Can never be initialized here.
    static const char* cs; // Same with C strings.

    static const int i = 3; // Integral types can be initialized here (*)...
    static const int j; //     ... OR in cpp.
};

toto.cpp

#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;

(*) Selon les normes, vous devez définir en idehors de la définition de classe (comme l' jest) si elle est utilisée dans du code autre que de simples expressions constantes intégrales. Voir le commentaire de David ci-dessous pour plus de détails.

squelart
la source
27
J'ai voté pour, mais après avoir examiné la norme, il y a une erreur dans votre code: idoit être défini dans le cpp. §9.4.2 / 4 Si une donnée membre statique est de type const intégrale ou énumération const, sa déclaration dans la définition de classe peut spécifier un initialiseur de constante qui doit être une expression constante intégrale (5.19). Dans ce cas, le membre peut apparaître dans des expressions constantes intégrales. Le membre doit toujours être défini dans une portée d'espace de nom s'il est utilisé dans le programme et la définition de portée d'espace de nom ne doit pas contenir d'initialiseur.
David Rodríguez - dribeas
3
Sur la base de votre citation des normes, il semble qu'il ne ifaudrait le définir que s'il était utilisé ailleurs que dans des expressions constantes intégrales, n'est-ce pas? Dans ce cas, vous ne pouvez pas dire qu'il y a une erreur parce qu'il n'y a pas assez de contexte pour être sûr - ou strictement, l'exemple ci-dessus est correct s'il n'y a pas d'autre code. Maintenant, j'apprécie votre commentaire (+1), j'apprends encore des choses moi-même! Je vais donc essayer de clarifier ce point dans la réponse, s'il vous plaît laissez-moi savoir si c'est mieux ...
squelart
@squelart Désolé si j'ai l'air stupide mais un exemple de déclaration autre qu'une expression constante intégrale serait?
Saksham
3
@Saksham Par exemple, appeler une fonction, par exemple: int f() { return 42; } class foo { static const int i = f(); /* Error! */ } Notez que C ++ 11 permet d'appeler des fonctions 'constexpr':constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
squelart
@squelart J'ai lu le texte de telle sorte que la définition doit être fournie si le membre est utilisé - le libellé de la norme ne limite pas cette exigence aux expressions constantes intégrales.
VladLosev
12

Les membres statiques doivent être initialisés dans une unité de traduction .cpp à la portée du fichier ou dans l'espace de noms approprié:

const string foo::s( "my foo");
Michael Burr
la source
11

Dans une unité de traduction au sein du même espace de noms, généralement en haut:

// foo.h
struct foo
{
    static const std::string s;
};

// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives

// bar.h
namespace baz
{
    struct bar
    {
        static const float f;
    };
}

// bar.cpp
namespace baz
{
    const float bar::f = 3.1415926535;
}
GManNickG
la source
8

Depuis C ++ 17, le spécificateur en ligne s'applique également aux variables. Vous pouvez maintenant définir des variables de membre statiques dans la définition de classe:

#include <string>

class foo {
public:
   foo();
   foo( int );
private:
   inline static const std::string s { "foo" };
};
plexando
la source
1

Seules les valeurs intégrales (par exemple static const int ARRAYSIZE) sont initialisées dans le fichier d'en-tête car elles sont généralement utilisées dans l'en-tête de classe pour définir quelque chose comme la taille d'un tableau. Les valeurs non intégrales sont initialisées dans le fichier d'implémentation.

Behnam Dezfouli
la source