Base class pointer versus inherited class pointer?

Suppose I have a class Dogthat inherits from a class Animal. What is the difference between these two lines of code?

    Animal *a = new Dog();
    Dog *d = new Dog();

In one, the pointer is for the base class, and in the other for the derived class. But when will this difference become important? For polymorphism, any of them will work in exactly the same way, right?

+5
source share
8 answers

For all type checking purposes, the compiler considers ait as if it could point to any Animal, although you know that it points to a Dog:

  • a , Dog*.
  • a->fetchStick(), fetchStick - Dog, Animal.
  • Dog *d2 = dynamic_cast<Dog*>(d) - , . Dog *d3 = dynamic_cast<Dog*>(a), , ( , - . , , , a d ).
  • .

( ) . , Dog , ( , JaredPar).

, Animal, () Dog, a d.

+11

- :

, . ++ - , - .

, , .

class Animal {
public:
  virtual void MakeSound(const char* pNoise) { ... }
  virtual void MakeSound() { ... }
};

class Dog : public Animal {
public:
  virtual void MakeSound() {... }
};

int main() {
  Animal* a = new Dog();
  Dog* d = new Dog();
  a->MakeSound("bark");
  d->MakeSound("bark"); // Does not compile
  return 0;
}

, , ++ . : ++ , , . , . Dog MakeSound , .

+4

Animal :

Animal *a = new Dog();
a->eat(); // assuming all Animal can eat(), here we will call Dog::eat() implementation.
a->bark(); // COMPILATION ERROR : bark() is not a member of Animal! Even if it available in Dog, here we manipulate an Animal.

( ), as a Animal, a , , Dog:

void toy( Dog* dog );

toy( a ); // COMPILATION ERROR : we want a Dog!

:

Dog *a = new Dog();
a->bark(); // works, but only because we're manipulating a Dog

, "" ( (), , ).

+2

, . , , do_stuff().

  • Animal:: do_stuff() , do_stuff() Animal Dog:: do_stuff().

  • Animal:: do_stuff() , do_stuff() Animal Animal:: do_stuff().

​​ :

#include <iostream>

class Animal {
public:
        void do_stuff() { std::cout << "Animal::do_stuff\n"; }
        virtual void virt_stuff() { std::cout << "Animal::virt_stuff\n"; }
};

class Dog : public Animal {
public:
        void do_stuff() { std::cout << "Dog::do_stuff\n"; }
        void virt_stuff() { std::cout << "Dog::virt_stuff\n"; }
};

int main(int argc, char *argv[])
{
        Animal *a = new Dog();
        Dog *b = new Dog();

        a->do_stuff();
        b->do_stuff();
        a->virt_stuff();
        b->virt_stuff();
}

:

Animal::do_stuff
Dog::do_stuff
Dog::virt_stuff
Dog::virt_stuff

. .

+2

, .

Dog , Animal. , , - Dog. Dog , .

Animal Animal: Dog, Cat, Wildebeast ..

+1

, Dog, Animal. ( Animal) Dog. , . Animal:: non_virtual_method() ( Animal), Dog:: non_virtual_method ( Dog).

0

, 2 , .

2 Dog . , Dog. Dog + Animal + vtable.

a d (lvalues) . , . , Animal * a , a- > Bark(), Dog:: Bark(). d- > Bark() .

vtable , , Animal Animal:: Move() Dog Dog:: Move() { }.

Animal a * a- > Move(), vtable, () { }. - , Animal:: Move() () , Dog's:: Move() Dog().

0

, . , , , d- > bark(), a- > bark(), . .

-1

All Articles