-2

I have just learnt about abstract class but I don't understand much. Is it possible to run abstract class functions and the inherited functions all at once?..

For example,

class Animals
{
 public:
    virtual void Display() = 0;
};

class Dog : public Animals
{
    void Display()
    {
        cout << "This is Dog!" << endl;
};

class Cat : public Animals
{
    void Display()
    {
        cout << "This is Cat!" << endl;
    }
};

and I have another class called Zoo which will run the abstract function in class Animals

class Zoo : public Animals
{
   Animals* animal;
   animal->Display();
}

and the output I want is

This is Dog!
This is Cat!

When I run this, it has errors.. Is there any other ways to get this output? Thanks :)

Benjan
  • 21
  • 1
  • 7
  • 1
    `Dog dog; Cat cat; dog.Display(), cat.Display();` ? – Jarod42 Feb 07 '18 at 19:14
  • 1
    `Animals* animal;` is an uninitialized pointer. Dereferencing it invokes *undefined behavior* – UnholySheep Feb 07 '18 at 19:14
  • Is there a way to only call the base class and run the inherited classes too? – Benjan Feb 07 '18 at 19:15
  • @Benjan: There's no implementation in the base class, so how would you call it? If there was, you could say Animal::Display() from within Dog::Display() – AndyG Feb 07 '18 at 19:16
  • 2
    By the way the code for `Zoo` wouldn't compile anyway - if you have errors please create a [mcve] and give the exact error message – UnholySheep Feb 07 '18 at 19:16
  • I'm afraid you misunderstand inheritance and virtual functions completely. What book do you use? – Christian Hackl Feb 07 '18 at 19:17
  • 1
    You need [a good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list?lq=1). This question really doesn't make any sense. – Rob K Feb 07 '18 at 19:36

3 Answers3

0

First off, there's a syntax error:

 class Animals
{
 public:
    virtual void Display() = 0;
};

class Dog : public Animals
{
    void Display()
    {
        cout << "This is Dog!" << endl;
    }
};

class Cat : public Animals
{
    void Display()
    {
        cout << "This is Cat!" << endl;
    }
};

Then if you want to create Dog and Cat instances you call new operators for these classes:

class Zoo : public Animals
{
   void Display() 
   {
       Animals* animal1;
       animal1 = new Cat();
       animal1->Display();
       delete animal1;

       Animals* animal2;
       animal2 = new Dog();
       animal2->Display();
       delete animal2;
   }

}

This should get your desired output.

Victor
  • 461
  • 1
  • 5
  • 14
0

Is there a way to only call the base class and run the inherited classes too?

I think you want this:

#include <iostream>
#include <memory>

class Animals
{
public:
    virtual void Display() = 0;
    virtual ~Animals() = default;
};

class Dog : public Animals
{
    void Display() override
    {
        std::cout << "This is Dog!" << std::endl;
    }
};

class Cat : public Animals
{
    void Display() override
    {
        std::cout << "This is Cat!" << std::endl;
    }
};

class Goat : public Animals
{
    void Display() override
    {
        std::cout << "This is Goat!" << std::endl;
    }
};

int main()
{
    Animals* animal = new Dog;
    animal->Display();
    delete animal; // delete at some point to avoid memory leak as Dog is allocated on the heap

    Cat cat;
    animal = &cat;
    animal->Display(); // no delete needed, as Cat is allocated on the stack and will cleared when goes out of scope

    std::unique_ptr<Animals> animal2 = std::make_unique<Goat>();
    animal2->Display(); // no delete needed, Goat is allocated on the heap but will be cleared when goes out of scope

    return 0;
}

https://ideone.com/yoVt4G

Threw std::unique_ptr in the mix for variety

Killzone Kid
  • 6,171
  • 3
  • 17
  • 37
  • Why raw pointers and not `std::unique_ptr`? And where are the `delete`s? Teaching this stuff to a beginner and not even mentioning `delete` is a bad idea. – Christian Hackl Feb 07 '18 at 19:33
  • You’re leaking both the `Cat` and `Dog` instances. I highly recommend wrapping them in `unique_ptr`s or at the very least `delete`ing them at the end of `main()`. – besc Feb 07 '18 at 19:38
  • Removed my downvote because `delete` is now mentioned. – Christian Hackl Feb 07 '18 at 19:40
0

animal->Display(); results in undefined behaviour because animal is not initialized, so first initialized it as

    Cat my_cat;
    Animals* animal = &my_cat;
    animal->Display();

OR

 Animals* animal = new Cat();
 animal->Display();
 ....
 delete  animal; 

Here is your Code, explanation is there in comments.

class Animals {
        public:
                virtual void Display() = 0;/*its a PVF , in every derived class it should be re-defined */
};

class Dog : public Animals {
        void Display() {
                cout << "This is Dog!" << endl;
        };
};
class Cat : public Animals {
        void Display() {
                cout << "This is Cat!" << endl;
        }
};

class Zoo : public Animals {
        public :
                void Display() {
                        #if 1
                        Dog my_dog;
                        Animals *animal = &my_dog; /** Display() of Animal class will be invoked  bcz Display() is declared as  virtual */
                        animal->Display();
                        #endif
                        #if 0
                        Animals* animal = new Cat(); /** Display() of Cat class  eill be invoked */
                        animal->Display();
                        delete animal;
                        #endif
                }
};
int main() {
        Zoo my_zoo;
        my_zoo.Display();
        return 0;
}

I hope it helps you.

Achal
  • 11,821
  • 2
  • 15
  • 37