2009-08-25 6 views
7

Impossible de lier deux fichiers après, lorsque je supprime le mot clé "statique", alors ça va. Testé avec g ++. Vérifiez avec liself pour le fichier objet, le membre statique semble être exporté comme un symbole d'objet global ... Je pense que ce devrait être un objet local ...?Définition multiple pour un membre statique?

static1.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

static2.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void second() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

avec des informations d'erreur:

/tmp/ccIdHsDm.o:(.bss+0x0): multiple définition de `StaticClass :: a '

Répondre

16

Il semble que vous essayez d'avoir des classes locales dans chaque fichier source, avec le même nom. En C++, vous pouvez encapsuler les classes locales dans un espace de noms anonyme:

namespace { 
class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
} // close namespace 

void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 
+0

@Ropez: ça marche bien. Merci :) –

+0

Je me sens mal avec l'état des choses, puisque la réponse de ropez semble t'avoir donné la solution que tu cherchais. n'hésitez pas à déplacer la coche à son :) :) +1 pour lui, de toute façon. –

+0

@Litb, vous avez tous les deux raison :) vous avez expliqué plus. –

0

StaticClass besoin d'un emplacement pour stocker a, une variable statique qui sera partagée par toutes les instances de classe - il y a deux lignes qui le font, une dans chaque fichier. Supprimer un corrigera l'erreur de l'éditeur de liens.

9

Voici une définition du membre de données statiques. Il doit se produire uniquement dans un fichier qui est compilé puis lié.

int StaticClass::a = 0; 

Si vous avez plusieurs ces définitions, il est comme si vous aviez plusieurs fonctions appelées first. Ils vont s'affronter et l'éditeur de liens va se plaindre.

Je pense que vous confondez les membres statiques avec des variables statiques appliquées à des variables d'espace de noms. Au niveau de l'espace de noms, static donne la liaison interne variable ou de référence. Mais au niveau de la portée de la classe (lorsqu'il est appliqué à un membre), il deviendra un membre statique - celui qui est lié à la classe au lieu de chaque objet séparément. Cela n'a alors plus rien à voir avec la signification C de "statique".

+0

Le problème est que je pense que l'éditeur de liens doit savoir lier la variable dans son fichier objet local, car il est une variable statique locale, et non statique globale un. –

+0

ce n'est ni local ni global. c'est un membre de la classe. http://en.wikipedia.org/wiki/Class_variable –

+2

@arsane, Si vous voulez une classe locale, vous devez la placer dans un espace de noms anonyme.Comme vous l'écrivez, StaticClass de static1.cpp est la même classe que StaticClass de static2.cpp. Avant de dire que les classes ne sont pas définies dans un en-tête, n'oubliez pas que le macropreprocesseur fonctionne par inclusion textuelle. – AProgrammer

2

La déclaration

int StaticClass::a = 0; 

alloue effectivement le stockage de la variable, c'est pourquoi il doit être écrit seulement une fois. Comme pour votre remarque, vous confondez probablement deux utilisations différentes du mot-clé static. En C statique, on entendait par «utilisation de la liaison interne», cela signifiait que le nom d'une variable ou d'une fonction ne serait pas visible en dehors de l'unité de traduction où elle était définie.

Dans les classes, static est utilisé pour définir des membres de classe, c'est-à-dire des variables ou des méthodes qui ne font pas référence à une instance spécifique de la classe. Dans ce cas, le stockage d'une variable statique doit être affecté quelque part (car il ne fait partie d'aucune instance), mais uniquement à un endroit bien sûr.

Questions connexes