0

So, I have 2 classes, one inherited by other and enum class,which does not play a role in my question, but I will quote it anyway:

enum class PetType {
    Cat,
    Dog,
    Q
};

class Pet {

protected:
    std::string name;
    size_t age;
    std::string breed;
    static PetType spice;


public:
    ...
    friend std::ostream& operator<< (std::ostream& out, const Pet& pet);
    friend std::ostream& operator<< (std::ostream& out, const PetType& pet);
};

class Dog : public Pet {

private:
    static PetType spice;
public:
    ...
};
PetType Dog::spice = PetType::Dog;
PetType Pet::spice = PetType::Q;

The main problem is here: i have an 2 operator's <<. First one is just help for me to cout<<PetType. Second one looks like these:

std::ostream& operator<< (std::ostream& out, const Pet& pet) {
    out << "My name is " << pet.name << std::endl;
    out << "I am " << pet.spice << ", " << pet.breed << std::endl;
    out << "I am " << pet.age << " years old" << std::endl;
    return out;
}

And, I have a vector with different Pet's. In the function of outputting this vector to the console, I cycle through it with cycle for and do smth like this:

std::cout << pets[i];

I want it to output my petType, of course. But it's outputting Q as my petType, which i choose a basic one for abstract class Pet. How can i fix this, please help!!!

  • There is no virtual dispatch for variables, even less so for _static_ variables. You have to have a virtual method for that. – tkausl Mar 12 '23 at 15:15
  • I have tryed that. It was getSpice, but it also didn't work for me. I don't know why – игорь кочнов Mar 12 '23 at 15:17
  • Please take some time to refresh the chapters and sections about polymorphism and virtual functions in your beginners material. – Some programmer dude Mar 12 '23 at 15:18
  • Like pointed out by tkausl, you need a virtual function on your Pet class, and the same function signature on your Dog class. Then, your vector of Pets need to contain pointers to your Pet class (or better, smart pointers). Polymorphism only works on pointers or references, but since a vector has value semantics, you need to use pointers, i.e `std::vector` . – Fauth Mar 12 '23 at 15:49
  • See also [here](https://stackoverflow.com/q/31776541/509868) – anatolyg Mar 12 '23 at 16:02

1 Answers1

3

As others have pointed out, you cannot use static members for inheritance. You can have them, but you cannot override them like this and expect them to resolve like they were virtual. As far as operator<< is concerned, it knows it is working with the Pet class only so it will always return that static member, not the one from Dog. If you fed it the Dog class, it would return the member value from that one instead.

You have a few options, don't make PetType spice static and in the Dog constructor assign the appropriate enum type like this:

class Pet {

protected:
    ...
    PetType spice;


public:
    ...
    friend std::ostream& operator<< (std::ostream& out, const Pet& pet);
    friend std::ostream& operator<< (std::ostream& out, const PetType& pet);
};

class Dog : public Pet {

public:
    Dog() : spice(PetType::Dog) {}
};
std::ostream& operator<< (std::ostream& out, const Pet& pet) {
    out << "My name is " << pet.name << std::endl;
    out << "I am " << pet.spice << ", " << pet.breed << std::endl;
    out << "I am " << pet.age << " years old" << std::endl;
    return out;
}

Or create a virtual method and override it

class Pet {

protected:
    ...
    virtual PetType getSpice(void) = 0;


public:
    ...
    friend std::ostream& operator<< (std::ostream& out, const Pet& pet);
    friend std::ostream& operator<< (std::ostream& out, const PetType& pet);
};

class Dog : public Pet {

public:
    ...
    PetType getSpice(void) override {return PetType::Dog;}

};
std::ostream& operator<< (std::ostream& out, const Pet& pet) {
    out << "My name is " << pet.name << std::endl;
    out << "I am " << pet.getSpice() << ", " << pet.breed << std::endl;
    out << "I am " << pet.age << " years old" << std::endl;
    return out;
}
deviantgeek
  • 121
  • 3