0
votes

Why isn't my object being created?
And how can I execute AllReferrals.push_back(this); from my constructor?

When I do it like so, I am told

error C2065: 'AllReferrals' : undeclared identifier

as well as

error C2228: left of '.push_back' must have class/struct/union

If I put the list initialization before the class I get

error C2065: 'AllReferrals' : undeclared identifier

Here is my 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);
}
3
I'm not your compiler. Why don't you explain what you're trying to ask for?JSBձոգչ
Sorry, was just trying to keep things interesting.Nona Urbiz
@Nona: I still have the same advice I gave you in the last question about this same code (previous version of it): You should state what your intentions are and then people can help you with comments on how to achieve your goal.David Rodríguez - dribeas

3 Answers

3
votes

AllReferrals name have to be declared before it's use when you read the file from top to bottom.

If not declared, the compiler don't know that it exists. That's what the error say.

To fix your problem, just move the declaration before it's use and use "forward declaration" for the type that you need a name for but is not defined yet.

#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();
}

As commenters added, another solution would be to move the constructor definition under the AllReferrals definition. Anyway it's always a name apparition order problem.

2
votes

Your first problem is that AllReferrals must be declared before you can use it. However, the Referral class must be defined before your declaration of AllReferrals. You can solve this by splitting the declaration and definition of the Referral constructor, like so:

.
.
.
    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);
}
.
.
.

Then you need to realise that this is a pointer, and you have declared your list to store actual object data. You can solve this in two ways:

  • change AllReferrals.push_back(this); to AllReferrals.push_back(*this);. This will cause a copy of the object to be placed on the list, which will Just Work but may have performance implications.

  • change the declaration of static list<Referral> AllReferrals; to static list<Referral *> AllReferrals;. This on its own will not give you working code, since Referral is being created on the locally in submit() and when you leave submit() the object will be discarded and the pointer left dangling. You can change Referral(url, keyword, occurrences); in submit() to new Referral(url, keyword, occurrences); which will cause the object to persist until deleted; but you must then make sure you delete all the Referral objects you created in this way when you are done with them, or you will leak memory - not permanently, the OS will clean up after you when your application terminates, but it may cause you problems if you are planning on creating lots of them.

1
votes

Try something more like this:

...

class Referral;

static list<Referral> AllReferrals;

class Referral
{
...
};