Polymorphic Interfaces

By convention, UVS interface classes begin with a capital "I". These classes contain nothing but pure virtual functions and a do-nothing virtual destructor; e.g.:

class IDiDist // discrete statistical distribution
{
public:
	virtual double // mean
	mean() const = 0;

	virtual double // variance
	variance() const = 0;

	virtual double // standard deviation
	stdev() const = 0;

	virtual PROB // probability function
	pf(DRAND) const = 0;

	virtual PROB // cumulative distribution function
	cdf(DRAND) const = 0;

	virtual
	~IDiDist() {}
};

Although you cannot create an instance of such a class it forms a common type for related classes. You might use one as follows:

	std::vector<IDiDist*> my_vec;
	my_vec.push_back(new Poisson(6.3));
	my_vec.push_back(new Binomial(15, 0.3));

These push_back statements are legal because a Poisson is an IDiDist and so is a Binomial. Although you cannot create containers of different types you can, as shown above, have a container of pointers to a common base type. This can be quite convenient in various situations.

The problem with this approach is that you must remember to delete the pointers before they are destroyed (for instance when the container goes out of scope). Otherwise you will have a memory leak. To avoid this problem it is recommended that you use a reference counted smart pointer:

	#include "boost/smart_ptr.hpp" // for boost::shared_ptr
	typedef boost::shared_ptr<IDiDist> PDiDist;
	std::vector my_vec;
	my_vec.push_back(PDiDist(new Poisson(6.3)));
	my_vec.push_back(PDiDist(new Binomial(15, 0.3)));

The advantage of this is that you no longer have to worry about deleting the pointers because the smart pointer does it for you automatically. The smart pointer referred to above is available at http://www.boost.org.

Continuing the previous example:

	std::cout << my_vec.front()->mean(); // calls uvs::Poisson::mean()
	std::cout << my_vec.back()->mean(); // calls uvs::Binomial::mean()

Because all discrete distributions are derived from IDiDist we can get certain basic functionality without knowing or caring which distribution type we have in the container.

The interface classes defined in UVS include: