Hi guys,

I'm having this weird error with undefined references to static variables, and was wondering what I'm doing wrong.

Here's the header:
World.h

#ifndef WORLDH
#define WORLDH
#include <vector>
using std::vector;

#include "Breeture.h"
class World{
    friend class Breeture;

    public:
    World(vector<Breeture*> *initialBreetures);
    World(unsigned int mutChance, unsigned int breetures);

    void NewBreeture(const Breeture *const baby);
    void BaiBreeture(const Breeture *const deceased);

    /*This function ages all living breetures*/
    void AgeBreetures();

    /*Does a death-check. World makes Breetures die.*/
    void DeathCheck();

    /*World also makes breetures mate.*/
    void BirthCheck();

    void outputAllData();

    unsigned int getWorldPopulation(){
        return worldPopulation;
    }

    unsigned int getTotalBreetures(){
        return totalBreetures;
    }

    bool verboseMode;

    //int StoreFamilyTree(string *location);

    private:
    static unsigned int worldPopulation;
    static unsigned int totalBreetures;

    /*This number is the limiting factor, resembling the lack of a certain resource (food, space) for Breetures*/
    unsigned int maxBreetures;

    Breeture *oldest;
    Breeture *mostChildren;

    /*Holds a vector of living creatures, for speedy aging*/
    vector<Breeture*> livingBreetures;

    /*Holds a tree of vector describing parent/child relationships*/
    vector<Breeture*> familyTree;
};
#endif

World.cpp

#include <vector>
using std::vector;

#include "Breeture.h"
#include "World.h"

World::World(vector<Breeture*> *initialBreetures) {
    livingBreetures = *initialBreetures;
    worldPopulation = livingBreetures.size();
    return;
}

World::World(unsigned int mutChance, unsigned int breetures) {
    Breeture::mutationChance = mutChance;

    //reserve memory to save reallocating x times
    livingBreetures.reserve(breetures);

    worldPopulation = totalBreetures = breetures;

    //create breetures breetures
    for (unsigned int i = 0; i < breetures; i++) {
        livingBreetures[i] = new Breeture();
    }

    return;
}

void World::AgeBreetures() {
    for (unsigned int i = worldPopulation; i >= 0; i--) {
        livingBreetures[i]->Age();
    }
    return;
}

void World::DeathCheck() {
    unsigned int DeathChance;
    for (unsigned int i = worldPopulation; i >= 0; i--) {
        DeathChance = livingBreetures[i]->deathChance;
        if (DeathChance == 1) {
            livingBreetures[i]->Die();
        } else {
            bool doesItDie = !(rand() % DeathChance);
            if (doesItDie) {
                livingBreetures[i]->Die();
            }
        }
    }

    return;
}

void World::BaiBreeture(const Breeture *const deceased) {
    //find the deceased breeture
    for (unsigned int i = worldPopulation; i >= 0; i--) {
        if (livingBreetures[i] == deceased) {
            livingBreetures.erase(livingBreetures.begin() + i);
        }
    }

    worldPopulation--;

    return;
}

void World::outputAllData() {
    for (unsigned int i = 0; i < worldPopulation; i--) {
        livingBreetures[i]->outputData();
    }
    return;
}

Now, this is my first project in C++ so I'm still learning. I thought I could reference to static variables like this, but apparently not. Here's the compiler output:

obj\Debug\World.o||In function `_ZSt24__uninitialized_copy_auxIPP8BreetureS2_ET0_T_S4_S3_11__true_type':|
C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\c++\3.4.5\bits\stl_algobase.h:(.text+0x10a)||undefined reference to `World::worldPopulation'|
obj\Debug\World.o||In function `_ZN5WorldC1EPSt6vectorIP8BreetureSaIS2_EE':|
C:\Code\Rapture\World.cpp|9|undefined reference to `World::worldPopulation'|
obj\Debug\World.o||In function `_ZN5WorldC2Ejj':|
C:\Code\Rapture\World.cpp|14|undefined reference to `Breeture::mutationChance'|
C:\Code\Rapture\World.cpp|19|undefined reference to `World::totalBreetures'|
C:\Code\Rapture\World.cpp|19|undefined reference to `World::worldPopulation'|
obj\Debug\World.o||In function `_ZN5WorldC1Ejj':|
C:\Code\Rapture\World.cpp|14|undefined reference to `Breeture::mutationChance'|
C:\Code\Rapture\World.cpp|19|undefined reference to `World::totalBreetures'|
C:\Code\Rapture\World.cpp|19|undefined reference to `World::worldPopulation'|
obj\Debug\World.o||In function `_ZN5World12AgeBreeturesEv':|
C:\Code\Rapture\World.cpp|30|undefined reference to `World::worldPopulation'|
obj\Debug\World.o||In function `_ZN5World10DeathCheckEv':|
C:\Code\Rapture\World.cpp|38|undefined reference to `World::worldPopulation'|
obj\Debug\World.o||In function `_ZN5World11BaiBreetureEPK8Breeture':|
C:\Code\Rapture\World.cpp|55|undefined reference to `World::worldPopulation'|
obj\Debug\World.o||In function `_ZN5World13outputAllDataEv':|
C:\Code\Rapture\World.cpp|67|undefined reference to `World::worldPopulation'|
obj\Debug\Breeture.o||In function `_ZN8BreetureC2Ev':|
C:\Code\Rapture\Breeture.cpp|41|undefined reference to `World::totalBreetures'|
C:\Code\Rapture\Breeture.cpp|41|undefined reference to `World::totalBreetures'|
obj\Debug\Breeture.o||In function `_ZN8BreetureC1Ev':|
C:\Code\Rapture\Breeture.cpp|41|undefined reference to `World::totalBreetures'|
C:\Code\Rapture\Breeture.cpp|41|undefined reference to `World::totalBreetures'|
obj\Debug\Breeture.o||In function `_ZN8Breeture3AgeEv':|
C:\Code\Rapture\Breeture.cpp|48|undefined reference to `Breeture::mutationChance'|
||=== Build finished: 17 errors, 0 warnings ===|

Thanks in Advance,
Nick

PS:
Previewing it, it looks quite unreadable. Sorry for that. Suggestions on how to make it more readable are welcome.

Recommended Answers

All 2 Replies

I apparently need to instantiate them somewhere.. but not in the constructor. :/

Nor in main because they are private...

It makes sense that I can't initialize them from the constructor, but not completely since I thought they were initalized to zero by default. However, how can I initialize private non-const static member variables then? Should I create a static-set function for those?

Thanks in Advance,
Nick

declare them at the top of world.cpp. You have to treat static class variable just like any other normal global variable.

#include <vector>
using std::vector;

#include "Breeture.h"
#include "World.h"


//initialize class static variables
unsigned int world::worldPopulation = 0;
unsigned int world::totalBreetures = 0;


World::World(vector<Breeture*> *initialBreetures) {
    livingBreetures = *initialBreetures;
    worldPopulation = livingBreetures.size();
    return;
}
<snipped>
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.