reference to abstract class

An abstract class is designed to be derived from. The Liskov substitution principle roughly states that anything that uses the abstract parts of types derived from an abstract base should work equally well using the base polymorphically. That means a reference or pointer to the base should be used.


A reference to an abstract class is just like a pointer to an abstract class: it needs to reference an object of some non-abstract subclass of the abstract class. You can use a reference like that to call virtual methods on the referenced class using the . syntax, in a way similar to a pointer to an interface in Java.


class Abstract
{
public:
  virtual void foo() = 0;
};

class Implementation : public Abstract
{
public:
  void foo() { std::cout << "Foo!" << std::endl; }
};

void call_foo(Abstract& obj) { obj.foo(); } 

int main()
{
  Abstract *bar = new Implementation();

  call_foo(*bar);

  delete bar;
}

bar is a pointer to an abstract class. It can be dereferenced using the * operator and passed as a reference into call_foo, because that is what call_foo is asking for (Abstract* would be asking for a pointer, whereas Abstract& is asking for a reference).

In the above, the reference to the abstract class is passed, and when foo() is called using the . notation (instead of the pointer -> notation), it prints Foo!, because that is what the Implementation does.

Hope this helps.


References in c++ behave (almost) like hidden pointers. In particular, the same polymorphic behavior you can get with a pointer, you can achieve it with a reference. That is, the following are (almost) equivalent

int *i = &a;
int &j = a;

assuming a was an integer defined somewhere in the previous lines. Following occurrences of the reference j, are perfectly equivalent to occurrences of (*i). The main difference is that a reference doesn't give you the pain of memory management, while a pointer does (it is your responsibility to handle new(s) and delete(s)). Also, a pointer doesn't have to point to something, while a reference can't exists if it's not referring to anything (1). Other than that, you can consider them to behave the same way.

Therefore, it's absolutely legal to have a reference to an abstract object. You will find it often in functions signatures, where the polymorphic behavior can be achieved either with references or pointers. But references give a lighter syntax, like the following piece of code shows

A a;
A* ptr = &a;
A& ref = a;
ref();
ptr->operator()();
(*ptr)();

assuming the class A overloads operator ().

(1) Well, you can have dangling references, just like pointers:

int* a = new int(1);
int& b = *a;
delete a; // et-voila, b is now dangling.

but they cannot be created without assigning something they can refer to.