Static Class Variables? Confusing message

I was trying to make a class that check how many objects you’ve made of it, and then prevents you from making any more if there are too many, but I’m getting a crazy error that is barely English at all, so I was wondering if anyone else could understand it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  #include <iostream>
  
  class Creature{
    static short CREATURE_AMOUNT;
    int hp;
    std::string name;
    public:
    Creature(int hpMx,const char * n = "kun") {
      CREATURE_AMOUNT++;
      if(CREATURE_AMOUNT >= 100){
        std::cerr << "Too many creatures";
        // deconstruct self
      }
    }
  };

  int main(){
    std::cout << "Hello, World!\n";
    Creature a(12);
  }


And then the error is:
/tmp/main-814f65.o:In function `Creature::Creature(int, char const*)':
main.cpp(.text.ZN8CreatureC2EiPKc[_ZN8CreatureC2EiPKc]+0x2b): undefined reference to `Creature::CREATURE_AMOUNT'
main.cpp(.text.ZN8CreatureC2EiPKc[_ZN8CreatureC2EiPKc]+0x37): undefined reference to `Creature::CREATURE_AMOUNT'
main.cpp(.text.ZN8CreatureC2EiPKc[_ZN8CreatureC2EiPKc]+0x3f): undefined reference to `Creature::CREATURE_AMOUNT'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
compiler exit status 1


So what is see is it doesn’t see CREATURE_AMOUNT, but I have no idea why or how to fix it.
Last edited on
That seems like a really weird software pattern. I would probably rather have logic external the constructor of an individual object that would dictate whether or not an object gets created.

In your class, you have declared the static variable. You now also need to define the static variable outside of the class.
https://www.tutorialspoint.com/cplusplus/cpp_static_members.htm

E.g. like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

class Creature{
  public:
    static short CREATURE_AMOUNT;
    
    Creature()
    {
        CREATURE_AMOUNT++;   
    }
};

short Creature::CREATURE_AMOUNT = 0;

int main(){
    Creature a;
}
Last edited on
ahh.. thank you!
Wait why make it external?
Because if the constructor of an object completes, what that represents is that the object is in a "good enough" state to be used (usually).

If I do
1
2
3
4
5
6
void func()
{
    Creature creature123; // ok
    Creature creature456; // BAD; max creatures reached?!
    creature456.attack(creature123); // ??
}

then what exactly does this even mean? If creature456 doesn't actually exist, I shouldn't be able to tell it to attack creature123 in the first place.

You could throw an exception inside creature456's constructor to clean up the mess, but what I would personally rather do instead, is have a container (e.g. vector) of Creatures, and if the user wants to add to this container, keeping letting them until the size of the vector is 100 or whatever. Then, if there are no more creature allowed, you simply prevent the creature's constructor from being called in the first place, by not calling push_back.
Last edited on
Topic archived. No new replies allowed.