2009-09-03 10 views
0

Pourquoi mon objet n'est-il pas créé?
Et comment puis-je exécuter AllReferrals.push_back(this); depuis mon constructeur?C++ conserver une liste d'objets et appeler un constructeur via une autre fonction

Quand je le fais comme si, on me dit

erreur C2065: 'AllReferrals': identificateur non déclaré

ainsi que

erreur C2228: gauche ' .push_back 'doit avoir class/struct/union

Si je mets l'initialisation de la liste avant la classe, je reçois

erreur C2065: 'AllReferrals': identificateur non déclaré

Voici mon code:

class Referral 
{ 
public: 
    string url; 
    map<string, int> keywords; 

    static bool submit(string url, string keyword, int occurrences) 
    { 
     //if(lots of things i'll later add){ 
     Referral(url, keyword, occurrences); 
     return true; 
     //} 
     //else 
     // return false; 
    } 

private: 
    list<string> urls; 

    Referral(string url, string keyword, int occurrences) 
    { 
     url = url; 
     keywords[keyword] = occurrences; 
     AllReferrals.push_back(this); 
    } 
}; 

static list<Referral> AllReferrals; 

int main() 
{ 
    Referral::submit("url", "keyword", 1); 
} 
+0

Je ne suis pas votre compilateur. Pourquoi n'expliquez-vous pas ce que vous essayez de demander? –

+0

Désolé, essayait juste de garder les choses intéressantes. –

+1

@Nona: J'ai toujours le même conseil que je vous ai donné dans la dernière question sur ce même code (version précédente): Vous devez indiquer quelles sont vos intentions et ensuite les gens peuvent vous aider avec des commentaires sur comment atteindre votre objectif. –

Répondre

3

nom de AllReferrals doivent être déclaré avant son utilisation lorsque vous lisez le fichier de haut en bas.

S'il n'est pas déclaré, le compilateur ne sait pas s'il existe. C'est ce que l'erreur dit.

Pour résoudre votre problème, déplacez simplement la déclaration avant son utilisation et utilisez "forward declaration" pour le type pour lequel vous avez besoin d'un nom mais qui n'est pas encore défini.

#include <iostream> 
#include <fstream> 
#include <regex> 
#include <string> 
#include <list> 
#include <map> 

using namespace std; 
using namespace tr1; 

class Referral; // forward declaration 
list<Referral> AllReferrals; // here 'static' is not needed 

class Referral 
{ 
public: 
string url; 
map<string, int> keywords; 

static bool submit(string url, string keyword, int occurrences) 
{ 
    //if(lots of things i'll later add){ 
    Referral(url, keyword, occurrences); 
    return true; 
    //} 
    //else 
    // return false; 
} 

private: 
list<string> urls; 

Referral(string url, string keyword, int occurrences) 
{ 
    url = url; 
    keywords[keyword] = occurrences; 
    AllReferrals.push_back(this); 
} 
}; 


int main() 
{ 
Referral::submit("url", "keyword", 1); 
cout << AllReferrals.size(); 
cout << "\n why does that ^^ say 0 (help me make it say one)?"; 
cout << "\n and how can i AllReferrals.push_back(this) from my constructor?"; 
cout << " When I do it like so, I am told error C2065: 'AllReferrals' : undeclared identifier"; 
cout << " as well as error C2228: left of '.push_back' must have class/struct/union."; 
cout << " If I put the list initialization before the class I get error C2065: 'AllReferrals' : undeclared identifier."; 
cout << "\n\n\t Thanks!"; 
getchar(); 
} 

Comme commenters ajouté, une autre solution serait de déplacer la définition du constructeur dans la définition de AllReferrals. De toute façon, c'est toujours un problème d'ordre d'apparition des noms.

+0

+1: ... déplace l'implémentation du constructeur en dessous de la définition de la liste. –

+0

Aussi devrait être 'AllReferrals.push_back (* this);' – pingw33n

+0

j'ai également eu besoin de déréférencer mon objet, donc push_back (* this); –

1

Essayez quelque chose comme ceci:

... 

class Referral; 

static list<Referral> AllReferrals; 

class Referral 
{ 
... 
}; 
2

Votre premier problème est que AllReferrals doivent être déclarés avant de pouvoir l'utiliser. Cependant, la classe Referral doit être définie avant votre déclaration de AllReferrals. Vous pouvez résoudre ce problème en divisant la déclaration et la définition du constructeur de référence, comme ceci:

. 
. 
. 
    Referral(string url, string keyword, int occurrences); // declaration 
}; 

static list<Referral> AllReferrals; 

Referral::Referral(string url, string keyword, int occurrences) // definition 
{ 
    url = url; 
    keywords[keyword] = occurrences; 
    AllReferrals.push_back(this); 
} 
. 
. 
. 

Ensuite, vous devez réaliser que this est un pointeur, et vous avez déclaré votre liste pour stocker des données d'objets réels. Vous pouvez résoudre de deux façons:

  • changement AllReferrals.push_back(this); à AllReferrals.push_back(*this);. Cela provoquera une copie de l'objet à placer sur la liste, qui fonctionnera juste mais peut avoir des implications de performance.

  • changez la déclaration de static list<Referral> AllReferrals; en static list<Referral *> AllReferrals;. Cela seul ne vous donnera pas le code de travail, puisque Referral est créé sur le localement dans submit() et quand vous laissez submit() l'objet sera rejeté et le pointeur laissé balancer.Vous pouvez changer Referral(url, keyword, occurrences); en submit() en new Referral(url, keyword, occurrences); ce qui entraînera la persistance de l'objet jusqu'à delete d; mais vous devez vous assurer que vous delete tous les objets Referral que vous avez créés de cette façon lorsque vous avez terminé avec eux, ou vous fuira mémoire - pas de manière permanente, le système d'exploitation nettoiera après vous lorsque votre application se termine, mais il peut vous causer problèmes si vous prévoyez de créer beaucoup d'entre eux.

+0

+1, C'est triste quand les gens demandent mais ne lisent pas les réponses ... ces mêmes corrections que vous venez de poster ont été postées par moi dans une question précédente. Peut-être que si assez de gens insistent pour cela ... –

+0

Je suis désolé, je ne l'ai pas compris dans ce contexte. Ici, ça m'a aidé. Pourquoi y a-t-il un problème avec ça? –

Questions connexes