Search code examples
c++inheritancestackvoidvoid-pointers

How to prevent a pointer of base class to point to derived class?


I have the following problem that looks like this.

class Animal
{
   void* value;
   public:
   Animal() {}
   void* getValue() {return value;} 
}

class IntAnimal : private Animal
{
  public:
  IntAnimal() {}
  int getValue() {return (*(int*)Animal::getValue());}
}

Basically the base class return void*, but the derived class return a regular type (int, double, char, etc).

I need to make either:

  1. We can do: Animal* intAnimal = new IntAnimal(); int x = intAnimal->getValue(); I think this is not possible.

  2. Prevent others from doing: Animal* intAnimal = new IntAnimal();

How do I prevent others from doing (2) ? Thank you.

Edit: yes this is a terrible design and I should use template. But, is there any other way to solve this problem?


Solution

  • There is nothing for you to do.

    Your current code forbids new IntAnimal(); for others in the first place, because the constructor is private.

    Even if you change that, your conditions are still satisfied. Since the Animal base is inherited as private, it is inaccessible to outside code and the implicit cast ill-formed.

    Animal* intAnimal = new IntAnimal();
    

    will not compile.

    Inside the class and friends the base class and constructor are always accessible and there is never an issue with that condition.


    It is impossible to prevent the implicit cast from IntAnimal* to Animal* if Animal is inherited as public by IntAnimal.


    Also note that inheritance being private does not prevent code from explicitly casting to Animal*. Any outside code can always use a C style cast

    Animal* intAnimal = (Animal*) new IntAnimal();
    

    which here behaves equivalent to the implicit cast, with the difference that it ignores the accessibility of the base class and will succeed independently of whether Animal is inherited as private or public.