Department of Engineering

IT Services

Things you probably don't need to know yet

virtual inheritance

Inheritance can be private (where even the public fields of the base class are treated as private), public (where the base class determines visibility), or virtual. With virtual inheritance there is only one copy of each object even if (because of multiple inheritance) the object appears more than once in the hierarchy. In the following example, derived1a and derived1b each contain a base object, but derived2 contains just one i field.

#include <iostream>
using namespace std;

class base{
  int i;

class derived1a: virtual public base {
  int j;

class derived1b: virtual public base {
  int k;

class derived2: public derived1a, public derived1b{
  int product() {return i*j*k;}

derived2 obj;
obj.i = 10;
obj.j = 3;
obj.k = 5;

cout << "product is" << obj.product() << '\n';
return 0;


In C++ you can identify the type of an object dynamically using RTTI (run-time type information). Given a type name, typeid returns a reference to a type_info object (in <type-info>). Can also give it an expression

#include <typeinfo>
void g(Component* p)
cout << typeid(*p).name();


Pointers to Members



typedef void (Std_interface::* Pstd_mem)();
void f(Std_interface* p)
Pstd_mem s= &Std_interface::suspend;

virtual destructors

You can't have virtual constructors, but you can have virtual destructors. They're not quite ordinary functions - no pointer to them is possible, for example).

Auto pointers

auto_ptr in <memory> - object pointed to will be deleted when pointer goes out of scope

operator functions

An operator function can be a member or non-member. The assignment, subscript, call and member selection operators are required to be class member functions.


A union is like a struct except that the fields occupy the same memory location with enough memory allocated to hold the largest item. The programmer has to keep a note of what the union is being used for. What would the following code print out?

union  person {
     int age;
     int height;
     char surname[20];
} fred;

fred.age = 23;
fred.height = 163;
cout << "Fred is " <<  fred.age << "years old\n";

If fred started at memory location 2000, then fred.age, fred.height and fred.surname would all begin at memory location 2000 too, whereas in a struct the fields wouldn't overlap. So setting fred.height to 163 overwrites fred.age (and the 1st 4 characters of fred.surname) making fred 163 years old.

Making New Containers


Non-type template parameters

Values as well as types can be used as template parameters.

template < class T, int size> 
class MyArray {

This lets the template create arrays of a fixed size (good for performance reason) but it means that a new piece of code will be created for each different class/size combination used.

Initialising from tables

Here's an example

class Club {
  string name;
  Table members;
  Table officers;
  Date founded;
  Club (cost stringg& n, Date fd);

Club::Club(cost string&n, Date fd)
     : name(n), members(n), officers(n), founded(fd)
// initialises from tables