Link to home
Start Free TrialLog in
Avatar of sebinfrancis
sebinfrancis

asked on

why references are not used in virtual mechanism

Usually we use base class pointer and points to some derived object and use virtual mechanism.

For eg:
base* b = new derived;
b->virtualfunction();

here virtual function defined in derived class will be executed.


derived* d = new derived;
base& b= *d;
b.virtualfunction();
 
in this case also derived class function will be called.

why we are not using references in virtual mechanism...

please reply......
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

>> why we are not using references in virtual mechanism

I don't understand the question. You can use both pointers and references to a base class from a polymorphic derived class to get polymorphic behaviour. The choice it up to you as the programmer which you choose.
Example.
#include <iostream>

struct animal
{
   virtual void noise() const = 0;
};

struct cat : animal
{
   void noise() const { std::cout << "meow" << std::endl; }
};

struct dog : animal
{
   void noise() const { std::cout << "bark" << std::endl; }
};

int main()
{
   animal const & a1 = cat();
   animal const & a2 = dog();

   a1.noise(); // meow
   a2.noise(); // bark
}

Open in new window

Avatar of sebinfrancis
sebinfrancis

ASKER

normally we use base class pointers to get polymorphic behavior.  I have not seen anybody using references for this even though it also works. Is there any drawback for reference  while it is used in polymorphic calls.
The behaviour semantics are identical only the syntax differs.
SOLUTION
Avatar of phoffric
phoffric

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
sebinfrancis,

Is there any specific reason you chose to ignore what I said? I specifically stated there is no compelling reason to use pointers over references and that it was purely a developer decision. The behaviour from a polymorphic point of view is identical. The example phoffric has given is specifically a design decision of using pointers rather than references but from a pure virtual function point of view the semantics are are identical (ie. you will get polymorphic behaviour regardless of using a pointer of reference as long as there is a v-table).

In other words, the solution you've selected doesn't answer your specific question, it just gives an example of when you might choose a pointer over a reference but equally there are plenty of reasons why you might choose a reference over a pointer. The simple fact is it is a design decision taken by the developer depending upon circumstances but there is no compelling reason to choose one over the other from a polymorphic point of view. I specifically stated this in my first point and provided a working example in my second. It seems you have chosen an answer that backs your assumption rather than one that actually correctly answers the question.

-Rx.
hi
i also know reference supports polymorphic behaviors like pointer. I have stated that in my first post. I just want to know then why it is not used normally in code( normal programming )

I think phoffric correctly explained it.  I am sorry if you misunderstood my question.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> when you are doing a lot of generic programming using templates and static polymorphism mixed with dynamic polymorphism the calling syntax is uniform.

As an example, the code below implements a (contrived but it is just to demonstrate the principle and is not an example of anything else) command pattern that mixes static polymorphism with dynamic polymorphism. In other words, you can prime the pattern with an object or reference to an object (with or without a polymorphic base class) and the behaviour is as expected in all circumstances, compiling without error and (in the case of dynamic types) calling the correct polymorphic override.

This code would be possible with pointers but because the calling syntax is different it would not compile without additional work to implement partial specialisations to accommodate the pointers calling syntax. Why would I bother when I can solve the same problem using just references and simpler, cleaner code?

In this case references provide a better solution (but not the only solution) in other cases pointers might be better. There is no one that is better than the other nor one that is generally preferred over the other (beyond programmer choice). The point is just because you can use pointers doesn't mean you would or should and vice versa... you choose the right tool for the job.
// this could also support pointers but it's just more work for no significant gain.

#include <iostream>

struct animal
{
   virtual void noise() const = 0;
};

struct cat : animal
{
   void noise() const { std::cout << "meow" << std::endl; }
};

struct dog : animal
{
   void noise() const { std::cout << "bark" << std::endl; }
};

struct machine
{
   virtual void noise() const = 0;
};

struct car : machine
{
   void noise() const { std::cout << "beep" << std::endl; }
};

struct van : machine
{
   void noise() const { std::cout << "roar" << std::endl; }
};

// A generic executor (representing something that might be used as part of the command design pattern).
// http://en.wikipedia.org/wiki/Command_pattern

template <typename T>
struct command
{
   command(T const & t) : t_(t)
   {
   }

   void operator()() const
   {
      t_.noise();
   }

   T const & t_;
};

void test_animal(animal & a)
{
   command<animal> cmd(a);
   cmd();
}

void test_machine(machine & m)
{
   command<machine> cmd(m);
   cmd();
}

template <typename T>
void test_generic(T const & t)
{
   command<T> cmd(t);
   cmd();
}

int main()
{
   cat c;
   dog d;
   car r;
   van v;

   command<animal> a1(c);
   command<animal> a2(d);
   command<machine> m1(r);
   command<machine> m2(v);

   a1();
   a2();
   m1();
   m2();

   command<cat> aa1(c);
   command<dog> aa2(d);
   command<car> mm1(r);
   command<van> mm2(v);

   aa1();
   aa2();
   mm1();
   mm2();

   test_animal(c);
   test_animal(d);

   test_machine(r);
   test_machine(v);

   test_generic(c);
   test_generic(d);
   test_generic(r);
   test_generic(v);
}

Open in new window

Hi evilrix,

Thank you very much for your detailed explanation.

Regards,
Sebin