Skip to main content
GameDev.net gamedev.net
🔒 Locked

static function can't find object.....?

Started by Alpha_ProgDes Feb 27, 2005 at 12:32 PM 14 replies 2.3k views
Original Post
Alpha_ProgDes
Alpha_ProgDes
i'm trying to pass a static enum variable to a static function in a class. it's not happening. why?

#ifndef PERSON_H
#define PERSON_H

enum Gender {MALE, FEMALE};
class Person {
    
    public:
         Person( );
         void returnGender () const;
         void lastGenderMade (Gender);
        
    private:
        
        
        static Gender makeGender ( );
        Gender gender;
};

#endif
and the source:

#include <iostream>
#include "Person.h"

using namespace std;

void Person::returnGender () const {
    
    if (gender == MALE)
        cout << "This person is MALE" << endl;
    else
        cout << "This person is FEMALE" << endl;
}

Person::Person () {
    gender = makeGender();
}

Gender Person::makeGender () {
    
    static int counter = 0;
    static Gender sex = MALE;
    
    if (counter == 0) {
        
        lastGenderMade(sex);  //line 25
    }
    else {
        lastGenderMade(sex);  //line 28
        if (sex == MALE)
            sex = FEMALE;
        else
            sex = MALE;
    }
    
    ++counter;    
    return sex;
}

void Person::lastGenderMade (Gender created) {
    
    if (created == MALE)
        cout << "This person is MALE" << endl;
    else
        cout << "This person is FEMALE" << endl;
}
here are the errors:

Person.cpp D:\Dev-Cpp5\Projects\Person.cpp In static member function `static Gender Person::makeGender()': 
25 D:\Dev-Cpp5\Projects\Person.cpp cannot call member function `void  Person::lastGenderMade(Gender)' without object 
28 D:\Dev-Cpp5\Projects\Person.cpp cannot call member function `void  Person::lastGenderMade(Gender)' without object 
Beginner in Game Development?  Read here. And read here.  
JimPrice
JimPrice
Isn't this because you're calling a non-static function from a static one? What's the this pointer?

Jim.
Alpha_ProgDes
Alpha_ProgDes
thanks very very much.
i can't believe i made that typo.
yes that function was supposed to be static.....

oh: JimPrice += 1
Beginner in Game Development?  Read here. And read here.  
silvermace
silvermace
thats a very missleading error message you have there.

ok, the reason is static member functions cannot access non-static member variabls AND non-static member functions. this is because static functions are not instanced per object, they are basically just global functions given the "namespace" or "alias" of the class, they have no notion of the this pointer.
Alpha_ProgDes
Alpha_ProgDes
now for a new problem.... nearly same code.
the code before was doing an unintended side effect.
so i decided to make a static Gender sex variable private.
and access in both functions. here's the code:
#ifndef PERSON_H#define PERSON_Henum Gender {MALE, FEMALE};class Person {        public:         Person( );         void returnGender () const;         static Gender lastGenderMade () ;            private:                        static Gender makeGender ( );        Gender gender;        static Gender sex;};#endif


and source:
#include <iostream>#include "Person.h"using namespace std;void Person::returnGender () const {        if (gender == MALE)        cout << "This person is MALE" << endl;    else        cout << "This person is FEMALE" << endl;}Person::Person () {    gender = makeGender();}Gender Person::makeGender () {        static int counter = 0;    sex = MALE;        if (counter == 0) {                lastGenderMade();    }    else {        lastGenderMade();        if (sex == MALE)            sex = FEMALE;        else            sex = MALE;    }        ++counter;        return sex;}Gender Person::lastGenderMade () {        return sex;}


error:
  [Linker error] undefined reference to `Person::sex' 

that errors shows up about 5 times.
Beginner in Game Development?  Read here. And read here.  
JimPrice
JimPrice
Well, firstly LastGenderMade isn't actually being used - it's returning sex (fnar fnar) but there's no l-value anywhere it's being used.

Next : your problem.

Static variables in classes need to be defined ex-class to ensure they exist. Hmm, that was badly explained - let's try some code.

At the start of your .cpp file add:

#include <iostream>#include "Person.h"using namespace std;// New line - definition of Person::sexGender Person::sex = MALE;


HTH,
Jim.
Nested Block
Nested Block
Yeah, what he said ^^

I believe you don't need the static keyword before Gender sex; and I think that's your problem. Enums ARE static and unchangable. Try that, I could be wrong.
"Your mother was a hamster and your father smelled of elderberries."
Alpha_ProgDes
Alpha_ProgDes
Quote:
Original post by Nested Block
Yeah, what he said ^^

I believe you don't need the static keyword before Gender sex; and I think that's your problem. Enums ARE static and unchangable. Try that, I could be wrong.


you could be right but JimPrice was spot on. thanks again Jim.
Beginner in Game Development?  Read here. And read here.  
JimPrice
JimPrice
Quote:

I believe you don't need the static keyword before Gender sex; and I think that's your problem. Enums ARE static and unchangable. Try that, I could be wrong.


I think you're missing the point of sex (double-entendre-tastic). Sex is a variable, of type Gender, that is static to class Person. The fact that the enum itself is global is beside the point - it's just a type to which sex belongs in this class.

Jim.
Alpha_ProgDes
Alpha_ProgDes
Quote:
Original post by JimPrice
Quote:

I believe you don't need the static keyword before Gender sex; and I think that's your problem. Enums ARE static and unchangable. Try that, I could be wrong.


I think you're missing the point of sex (double-entendre-tastic). Sex is a variable, of type Gender, that is static to class Person. The fact that the enum itself is global is beside the point - it's just a type to which sex belongs in this class.

Jim.

and i learned a new word in english and revisited a old word in french.
damn your good!
Beginner in Game Development?  Read here. And read here.  
Alpha_ProgDes
Alpha_ProgDes
Yet another problem....

sex doesn't keep its value after i changed it in the function makeGender().
obviously class static variables work differently than regular static variables. any ideas?
Beginner in Game Development?  Read here. And read here.  
JimPrice
JimPrice
Hello again!

Having returned from sunny Vancouver....

try the following:

#include <iostream>using namespace std;enum Gender {MALE, FEMALE};class Person {public:	Person() {gender_ = MakeGender();}	void PrintGender() const;        private:    static Gender MakeGender();    Gender gender_;    static Gender sex_;};Gender Person::sex_ = MALE;void Person::PrintGender() const{	std::cout << gender_ << std::endl;}Gender Person::MakeGender(){	if(sex_ == MALE)		sex_ = FEMALE;	else		sex_ = MALE;	return sex_;}int main(){	Person a;	a.PrintGender();	Person b;	b.PrintGender();	std::cin.get();}


Of course, if you want to make the first person male, then you need to change the ex-class static declaration.

Jim.
Zahlman
Zahlman
This can be written more simply (and also setting it up so that the static declaration specifies the first gender used, rather than the opposite), assuming NextGender() won't be needed anywhere else:

#include <iostream>using namespace std;enum Gender {MALE, FEMALE};class Person {  public:  Person() : gender(nextGender) { // use initializer list to set member    // do the gender-flipping logic that was in MakeGender()    if(nextGender == MALE) nextGender = FEMALE;    else nextGender = MALE;  }  void PrintGender() const { std::cout << gender << std::endl; }  // pardon my inlining ;)  // This way just prints an integer value, though, I think.  // - Hmm - shouldn't you put the enum the other way around so that female  // is 0 and male is 1? (ooh, more innuendo with digit shapes - oh,  // and more, with reference to digits... muahaha)  private:  Gender gender;  static Gender nextGender;};Gender Person::nextGender = MALE;
JimPrice
JimPrice
Who invited you anyway[razz]?

Jim.
iMalc
iMalc
Ah, tis a fine line between writing code as close as possible to how they wrote it (so that they can obviously understand it), and writing it how it best be written! Most of us aim for somewhere in the middle.
I assume you're intending to make a nice healthy ratio of females to males?
Alpha_ProgDes
Alpha_ProgDes
lol. pretty much. the intent of the program is to have the class be MALE then the next class be FEMALE then alternate back and forth as such.

the two functions are supposed to tell the user the current sex of the class and the sex of the prior class.

i'm having trouble getting the second function to work properly (well the mechancis of it anyway) it seems the class static member doesn't want to work the way i want it to [smile]
Beginner in Game Development?  Read here. And read here.  

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.