3

I'm not sure how to fix the following error

Cannot cast Cat to its private base class Animal

class Animal {
private:
    std::string name;
public:
    Animal(std::string n) {
        name = n;
    }
};

class Cat : Animal {
public:
    Cat(std::string n) : Animal(n) {}
};

class AnimalQueue {
private:
    std::list<Animal> cats;
    std::list<Animal> dogs;
public:
    void enqueue(Animal a) {
          if (typeid(a) == typeid(Cat)) {
                printf("I'm a cat\n");
          }
     }
}

int main() {
    AnimalQueue animalQ;
    Cat cat = Cat("kitty");
    animalQ.enqueue(cat); // ERROR
    return 0;
}
  • What is the actual compiler error? Keep in mind that even if this worked you'd end up slicing the object you placed in the list. You might consider a list of smart pointers instead. – Retired Ninja Dec 21 '14 at 22:52
  • 1
    Of course you can't. How about reading what a language feature does before using it? – Baum mit Augen Dec 21 '14 at 22:53
  • note that in the function `void enqueue(Animal a)`, `typeid(a) == typeid(Cat)` is always false. `a` has type `Animal`. (If you called this function with a Cat, then you sliced it). To fix this you'll have to take `a` by reference; and also `Animal` must contain a virtual destructor. – M.M Dec 21 '14 at 23:11
  • actually what worked is making the inheritance public –  Dec 21 '14 at 23:13
  • 1
    Slicing a cat is a crime – 6502 Dec 21 '14 at 23:13
  • Okay listen all, I'm doing a question in "cracking the coding interview" and this was their solution –  Dec 21 '14 at 23:15
  • [What is slicing?](http://stackoverflow.com/questions/274626/what-is-object-slicing) – M.M Dec 21 '14 at 23:15
  • Thanks, actually I'm wrong they gave the solution in java and I'm trying to convert it to c++, they're using "instanceOf" though –  Dec 21 '14 at 23:16
  • yes what I'm doing is wrong .. this is my next thing to figure out since I don't want the solution in Java as given in the book. I want to solve it in C++ –  Dec 21 '14 at 23:17
  • Please don't edit the question to contain the answer. Instead, accept a posted answer or post an answer of your own and accept it. – M.M Dec 21 '14 at 23:17
  • If you're coming from java, bear in mind that `Cat cat` or `Animal a` in C++ means an object by value, not an "object reference" like Java has. C++ doesn't have "object reference" , it has "value", "pointer" and "reference" which are each a bit different . IMHO it's better to not try to relate C++ to Java in this instance, just learn the C++ options afresh – M.M Dec 21 '14 at 23:19

3 Answers3

3

You can do this with a C-style cast:

animalQ.enqueue( (Animal &)cat );

This is one of the few cases where something is legal via a C-style cast but cannot be done with a C++-style cast. For further info see here.

It'd be a better design for the base class to use public inheritance though; private inheritance doesn't really have a valid use-case.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • I actually tried that same line and I saw the same error and was confused, let me try again. –  Dec 21 '14 at 23:09
  • @nevermind sorry, thought the enqueue function accepted a pointer (normally it would) so have updated my answer now. note that the slicing problem is still here – M.M Dec 21 '14 at 23:17
  • yes still here I'm reading the link you gave me it will take me a while to figure it out, thank you so much –  Dec 21 '14 at 23:18
3

By default, inheritance is private. You need to explicitly tell the compiler to use public inheritance. So, you need to declare your class with:

class Cat : public Animal {
cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106
1

this was the problem, I had to make it public

class Cat : public Animal