c++ invalid use of a class?

Discussion in 'Mac Programming' started by chris200x9, Apr 22, 2008.

  1. chris200x9 macrumors 6502a

    Joined:
    Jun 3, 2006
    #1
    Hi I'm writing a class and I want to invoke the print function and I keep getting the error invalid use of a class, my code looks like this:

    my cpp
    Code:
     
    #include "/home/chris200x9/Desktop/test4/Pet.h"
    #include <iostream>
    using namespace std;
    Pet::Pet(string n, int a, int w, string t)
    {
    	n = name;
    	a = age;
    	w = weight;
    	t = type;
    	
    	
    
    }
    Pet::~Pet(void)
    {
    };
    
     int Pet::Gain( int gain)
    {
    	return weight + gain;
    	};
    	
     int Pet::Loss( int loss)
    {
    	return weight - loss;
    };
    
    void Pet::Print()
    {
    	cout << name << endl;
    	cout << age << endl;
    	cout << weight << endl;
    	cout << type << endl;
    }
    int main()
    {
    	Pet one;
    	one.Pet.Print ("mincha",14,4,"dog");
    	return 0;
    }
    
    and my header file looks like this:

    Code:
     
    
    #include <string>
    
    using namespace std;
    
    class Pet
    {
    private:
        string name;
        int age;
    	int weight;
    	string type;
    
    public:
    	Pet(void);
    	Pet(string name, int age, int weight, string type);
    	~Pet(void);
    	void Print(void );
    	int Gain( int gain );
    	int Loss(int loss);
    };
    

    any help would be much appreciated :)
     
  2. neoserver macrumors 6502

    Joined:
    Apr 24, 2003
    #2
    Code:
    one.Pet.Print ("mincha",14,4,"dog");
    There is an error there. You've defined an instance of your class as "one." and to use a method of a class, you need to use the syntax
    Code:
    instance.method()
    You do not need to reference the class name as you have done in your code.

    Also, you have an issue with how you are instantiating the class. Your constructor method takes 4 arguments, but you haven't given it any. You've instead given these to the Print method which does not take any arguments.

    Replace it by
    Code:
    Pet one("mincha",14,4,"dog");
    one.Print();
    And you should be in business. Let me know if this doesn't make sense. :)
     
  3. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #3
    As an aside, i think in Gain and Loss you want to do something like:
    Code:
    int Pet::Gain(int gain)
    {
    	return weight += gain;
    };
    Otherwise you would have to pass the result to a mutator for weight, which doesn't exist right now.

    -Lee
     
  4. chris200x9 thread starter macrumors 6502a

    Joined:
    Jun 3, 2006
    #4
    thanx so much, neoserver, I didn't quite get what you meant by the first part.
     
  5. neoserver macrumors 6502

    Joined:
    Apr 24, 2003
    #5
    When you design a class, you can't use it until you create an "instance" (essentially, a working copy that the computer can use) of it. Once you've created an instance of it (Which I assume you know, since its essentially the same as declaring a variable), you can then use the functions, (or methods) that you've created in that class.

    The proper syntax to call a function (or method) in your class is:
    Code:
    instance_name.function_name(arguments);
    where instance_name, is the name of your instance, in your case, this was one, and function_name is the function you want to call.

    Previously you had
    Code:
    one.Pet.Print();
    This is invalid, given the class definition you built since there is no class member named "Pet" inside your class "Pet" (confusing I know.)

    I suggest you do some more reading on C++ classes, You'll be able to learn far more from that than me :)
     
  6. chris200x9 thread starter macrumors 6502a

    Joined:
    Jun 3, 2006
    #6
    ok, I have a problem when i do one.Print(); it doesn't print the strings it's just blank and for the 14 and four it just prints random int values? thanx again for everything.
     
  7. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #7
    Change your main to:
    Code:
    int main()
    {
    	Pet one("mincha",14,4,"dog");
    	one.Print();
    	return 0;
    }
    One was uninitialized. It was pointing to a random area of memory. The fields were just mapped to garbage in memory.

    I missed something else, you need to change the assignments in the constructor.
    Code:
    Pet::Pet(string n, int a, int w, string t)
    {
    	name = n;
    	age = a;
    	weight = w;
    	type = t;
    }
    -Lee
     
  8. chris200x9 thread starter macrumors 6502a

    Joined:
    Jun 3, 2006
  9. chris200x9 thread starter macrumors 6502a

    Joined:
    Jun 3, 2006
  10. alaceo macrumors member

    Joined:
    Feb 21, 2008
    #10
    If it is compiling, I'm surprised. Remove the semi colons after each function in the implementation - it is only needed after declaring the class. That should help you out some. Good luck.

    Example:

    Instead of
    Code:
    int Pet::Gain(int gain)
    {
    	return weight += gain;
    };
    
    Code:
    int Pet::Gain(int gain)
    {
    	return weight += gain;
    }
    
    Only needed here:
    Code:
    class Pet
    {
    	...........
    };
    
     
  11. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #11
    Unnecessary doesn't always mean incorrect. It would be best, since it appears chris200x9 is just starting to learn C++, that he learn what is necessary and what is not, but you shouldn't assert that something won't compile that is perfectly valid.
    Code:
    ;
    
    is a perfectly valid statement in C/C++. You can have as many as you'd like, in any block you'd like.

    This is a copy of chris200x9's code w/ the suggested corrections and some extra semi-colons:
    Code:
    #include "Pet.h"
    #include <iostream>
    using namespace std;
    ;;;;;
    Pet::Pet(string n, int a, int w, string t)
    {
            name = n;
            ;
            age = a;
            ;
            weight = w;
            type = t;
    
    
    
    }
    ;;;;;
    Pet::~Pet(void)
    {
    };
    ;;;;;;
     int Pet::Gain( int gain)
    {
            ;
            return weight += gain;
            };
    ;;;;;;;
     int Pet::Loss( int loss)
    {
            ;
            return weight -= loss;
    };
    ;;;;;;;
    
    void Pet::Print()
    {
            cout << name << endl;
            cout << age << endl;
            cout << weight << endl;
            ;;
            cout << type << endl;
    }
    ;;;;;;;
    int main()
    {
            Pet one("Mincha",14,4,"dog");
            ;;;
            one.Print();
            ;;;
            return 0;
    }
    ;;;;;;;
    
    It compiles and runs without issue. With all of that said, it certainly isn't necessary to have semi-colons after each function definition. It is necessary after a class definition because that statement is basically:
    Code:
    class Pet
    {
    ...
    };
    
    The semi-colon is ending the class statement.

    -Lee
     
  12. alaceo macrumors member

    Joined:
    Feb 21, 2008
    #12
    Hmm...I learned something today haha.
    Honestly, had no idea any compiler would allow that - thought one would complain of a syntax error. Never thought to try it.

    Thanks for the info lee! :D
     
  13. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #13
    no problem. I should note that there are cases that empty statements are problematic. If you use a single statement outside of turnstiles in an if-else block, then an extra empty statement will cause problems like any other statement. You will get a warning in many compilers if an empty statement is unreachable, again this is the same as any other statement.

    The worst case is sticking an empty statement where you don't mean to. As the body of a for loop, this can be a real headache.
    Code:
    int x;
    for(x=0;x<10;x++);
    {
      printf("x: %d\n",x);
    }
    
    The output will be:
    x: 10
    oops.

    As the body of a while loop it's easy to get an infinite loop. This can be even harder to track down.

    -Lee
     
  14. alaceo macrumors member

    Joined:
    Feb 21, 2008
    #14
    Ya, I've debugged a few of the lower classmen's apps with mistakes like those in it. Always a good time.

    I'm actually somewhat ashamed that in 3 years of C++ development I didn't know the semicolon could be used as randomly as you had shown. Oh well. You live, you learn.
    :)
     
  15. Sander macrumors 6502

    Joined:
    Apr 24, 2008
    #15
    Some more things to think about in your class design:

    - Should age and especially weight really be integers?
    - Should there be a default constructor (leading to the problem you ran into, that you can create an instance of a Pet with all its member variables uninitialized)?
    - Do you have to define a destructor?

    Happy C++ing!
     

Share This Page