2008-12-01 9 views
0

J'ai écrit un programme, qui était tout dans un fichier, et les méthodes ont été déclarées dans un en-tête. Le programme a initialement fonctionné parfaitement lorsqu'il était dans un fichier. Mais quand j'ai séparé le programme, j'ai continué à obtenir des occurrences aléatoires pour le destructeur de l'une des classes qui a été déclaré dans le fichier d'en-tête.Variables statiques, compilation séparée

J'ai une variable statique dans mon en-tête pour compter le nombre d'objets d'une classe particulière. Chaque fois que je construis l'objet, j'incrémente cette variable. Ensuite, dans mon destructeur, je soustrais 1 à cette variable, vérifie si c'est 0 (ce qui signifie que c'est le dernier objet) et fais quelque chose. La valeur semble parfois éteinte, je ne sais pas pourquoi. J'ai des appels aléatoires dans ma demande mais je ne vois pas pourquoi cela affecterait ce que j'ai décrit ci-dessus, merci. Toute aide ou compréhension est appréciée!

[Mise à jour]: avoir une classe de base, qui contient le destructeur .. qui est implémenté dans l'en-tête, puis j'ai deux classes dérivées, qui dans leur constructeur incrémentent la variable statique .. alors que puis-je faire?

Ce que je suis en train de faire est la suivante: Dans mon tête, j'ai ceci:

class A { 
public: 
    virtual ~A() { 
     count --; 
     if (count == 0) { /* this is the last one, do something */ } 
    } 

class B : public A { 
public: 
    B(); 
} 

Puis, en classe BI ont

B::B() { 
    count++; 
} 

Où puis-je définir compter donc je ne suis pas obtenir des chiffres trompeurs? Merci.

+0

La raison pour laquelle il ne correspond pas est parfois parce que le compilateur génère automatiquement le constructeur de copie pour vous. Le constructeur de copie par défaut n'incrémentera pas la variable count. –

Répondre

0
class A { 
public: 
    virtual ~A() { 
     count --; 
     if (count == 0) { // this is the last one, do something } 
    } 
protected: 
    static int count; 
}; 

class B : public A{ 
public: 
B(); 
}; 

Et puis, dans un et un seul de vos fichiers sources, vous devez mettre ce qui suit. Il devrait aller dans le fichier source qui contient le code pour la classe A.

int A::count(0); 

Vous devez faire cela, parce que le fichier d'en-tête a déclaré qu'il allait être un nombre variable du nom, mais n'a pas Allouer stockage pour cela. Si vous ne l'avez pas placé dans un fichier source, l'éditeur de liens se plaindrait qu'il n'a pas été trouvé.

+0

Toujours pas correct. –

+0

@Martin, bien sûr, vous avez raison. Je vais upvote votre réponse. –

+0

@Mark R: Merci. –

0

Pouvez-vous préciser ce que vous entendez par "la valeur semble être éteint"? Avez-vous trop de constructions? Pas assez de destructions? Si vous avez trop de constructions et pas assez de destructions, cela n'aura rien à voir avec la statique.

Aussi, que voulez-vous dire par une variable statique? Voulez-vous dire un champ de membre statique ou une variable statique réelle? Si vous déclarez simplement une variable statique dans l'en-tête (ce dont je doute que vous le fassiez), alors chaque fichier C qui inclut cet entête aura une instance distincte de cette variable (puisque static avant une variable globale signifie qu'il est limité à ce fichier objet).

+0

J'ai la variable statique dans mon en-tête, où puis-je la mettre parce que mon destructeur est défini dans l'en-tête et utilise cette variable, merci. – BobS

+0

@BobS, est la partie variable statique de la classe, ou en dehors du bloc de la classe? Vous le voulez probablement dans votre classe. Aussi, vous devez le définir (?) Dans l'un de vos fichiers .cpp afin qu'il soit exporté une fois. – strager

+0

J'ai une classe de base, qui contient le destructeur .. qui est implémenté dans l'en-tête, puis j'ai deux classes dérivées, qui dans leur constructeur incrémentent la variable statique .. alors que puis-je faire? – BobS

1

Où votre variable statique est-elle définie? Peut-être que vous le définissez accidentellement dans le fichier d'en-tête, et l'inlining est source de confusion (et le compilateur n'attrape pas les multiples définitions, ce qui serait étrange, mais on ne sait jamais).

Assurez-vous qu'une variable statique de classe est définie dans exactement une unité de traduction. Vous le définissez comme ceci:

int MyClass::static_var; 

Ceci est également l'endroit où vous placez l'initialiseur, le cas échéant.

+0

Salut, dans mon en-tête j'ai un destructeur qui devra appeler static_var. Mais j'ai aussi besoin d'appeler static_var dans mon constructeur pour mes deux classes dérivées, alors où puis-je placer cette ligne? – BobS

6

Vous devez définir le constructeur dans A (tous) pour incrémenter le nombre.

Remarque à moins que vous les définissez le compilateur génère automatiquement les quatre méthodes suivantes:

  • Constructor Par défaut (si aucun autre constructeur est défini)
  • Par défaut Destructeur
  • Copy Constructor
  • Opérateur d'affectation

Le code suivant remplace les valeurs par défaut du compilateur afin que y Vous devriez avoir un compte précis.

class A 
{ 
    static int count; 

    public: 
     A() // Default constructor. 
     { 
      ++count; 
     } 
     A(A const& copy) // Copy constructor/ 
     {     // Note If you do not define it the compiler 
      ++count;  // will automatically do it for you 
     } 
     virtual ~A() 
     { 
      --count; 
      if (count == 0) 
      { // PLOP 
      } 
     } 
     // A& operator=(A const& copy) 
     // do not need to override this as object has 
     // already been created and accounted for. 
}; 

//// Dans le fichier source:

int A::count = 0; 
Questions connexes