Archived

This topic is now archived and is closed to further replies.

gpalin

C++ inheritance problem

Recommended Posts

gpalin    164
I've been working in inheritance in C++ for a while now - I know the basics, at least. What I'm trying to do now is inherit a Hare class from a generic Animal class. The Animal class has speed, viciousness, laziness, name, and symbol attributes, which are normally initialized when I create a Hare object: Hare hare1(0.8,0.2,"Speedy",'@'); Now, what I want to do is have the Hare class contain two private static variables: speed and viciousness. Since these will always be the same in every Hare object, I want to have predefined values for speed/viciousness so their values don't have to be specified when creating the Hare object. So, what I do is this: Hare hare1("Speedy",'@'); And in the Hare constructor, I initialize the static values (which are declared in the .h file). That's fine. But when I send off the two static values and the given name/symbol values tot he Animal constructor, I get 4 errors, 2 each about no reference to the static values. I've got no idea what to do - any help? Here is the code I have for Animal and Hare: Animal.h
class Animal {
    public:
        /* Member functions */

        /* Purpose: constructor; initializes animal's attributes.
         * Takes: values for speed, viciousness, name, and symbol
         * Returns: nothing
         */
        Animal(double speed, double viciousness, string name, char symbol);
Animal.cpp
      
Animal::Animal(double inSpeed, double inViciousness, string inName,
    char inSymbol) {

    speed = inSpeed;
    //The animal's laziness is always equal to half it's speed

    laziness = speed / 2;
    viciousness = inViciousness;
    position = 0; //The animal always starts at position 0 (start of race)

    name = inName;
    symbol = inSymbol;
//    srand ( time(NULL) ); //Initialize random number generator

} //End Animal constructor

Hare.h
#include "Animal.h"

class Hare : public Animal {
    public:
        /* Member functions */

        //Constructor

        Hare(string name, char symbol);

    private:
        /* Attributes */
        static double speed;
        static double viciousness;

        //No extra attributes needed; inherited from Animal


}; //End class Hare

Hare.cpp
//The Hare constructor calls the Animal constructor to do the work.

Hare::Hare(string name, char symbol) :
    Animal(speed, viciousness, name, symbol) {
    speed = 0.8;
    viciousness = 0.2;

    //No need to do anything here.


} //End Hare Constructor

And these are the errors I get: c:\documents and settings\grant palin\my documents\school\comp160\race\hare.o(.text+0x72):hare.cpp: undefined reference to `Hare::viciousness' c:\documents and settings\grant palin\my documents\school\comp160\race\hare.o(.text+0x7e):hare.cpp: undefined reference to `Hare::speed' c:\documents and settings\grant palin\my documents\school\comp160\race\hare.o(.text+0xdd):hare.cpp: undefined reference to `Hare::speed' c:\documents and settings\grant palin\my documents\school\comp160\race\hare.o(.text+0xe9):hare.cpp: undefined reference to `Hare::viciousness' Thanks for any help. Grant Palin

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
i think you''ve got several problems, but first is namespace collision (or something like it) with the hare class having variables with the same name as it''s base class'' member variables.

(namely, speed and viciousness)

it might be better to name it Hare::HareViciousness and Hare::HareSpeed...

anyways, the specific problem you''re having is that you haven''t declared Hare::speed anywhere.

in your Hare.cpp, do the following:

double Hare::speed = .08;
double Hare::viciousness = .02;

and that should fix your link error.

i encourage you do to something like this, though:

class Hare
{
public:
static double HareSpeed;
static double HareViciousness;
}

and then

double Hare::HareSpeed = .08;
double Hare::HareViciousness = .02;

Hare::Hare(string name, char symbol) : Animal(Hare::HareSpeed, Hare::HareViciousness, name, symbol)
{

// don''t do anything here, because base constructor
// sets speed and viciousness, doesn''t it?

}

Share this post


Link to post
Share on other sites
gpalin    164
Thanks for your reply. I tried your suggestion, but it didn''t work - I still got the same errors.

So, I tried initializing those attrivutes inside the header file. When compiling, I got a new message about being unable to initialize non-const variables in the header file. So I made those variables const, and then it compiled and worked! Thanks for the tip though.

Grant Palin

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
yeah, for what you''re doing, its okay to have it be const.
but in general, if you declare a static variable inside a class, you have to do the following:

1) make sure you declare it (double Hare::speed) in a .cpp file
2) make sure you always refer to it as Hare::speed, not just speed... or else it won''t resolve it properly. (especially in your case, where Hare::speed and this->speed may be different because of the shared names.)

anyways, good luck. what i suggested should work (i just tried it, and g++ compiles it no problem.) so if you have a little time, it might be worth your while to figure out how to get non-const static class variables.

have fun.

Share this post


Link to post
Share on other sites
gpalin    164
Okay, thanks for the advice. I tried that, and it worked. I''ll have to file away that bit of information for future reference. Thanks!

Grant Palin

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Why do you need to have the static variables in the header? You have them listed in the private section so nobody else can see them, why don''t you just list them in an anonymous namespace in your cpp file?

In the first Anon. Poster''s response he lists it as:

class Hare
{
public:
static double HareSpeed;
static double HareViciousness;
}

This makes the HareSpeed and HareViciousness visible outside the class. Since it''s static you could do something like:

...
double someVariable = Hare::HareSpeed;
...

but since you have it in the private section you can''t do this. You might as well just leave it in the .cpp file like:

namespace
{
double HareSpeed;
double HareViciciousness;
}

Hare::Hare(...)
{
...
}

Share this post


Link to post
Share on other sites
gpalin    164
Are you talking about the original code I provided? If so, I''ve changed that according to the first AP''s suggestions.

Grant Palin

Share this post


Link to post
Share on other sites