Next Previous Up Top


5 Examples

5.1 A first example

5.1.1 - Reified class
5.1.2 - Proxy definition
5.1.3 - Using the reified class

5.1 A first example


This first simple example of the use of the europa standard just builds a class that prints out the name of each public member called. It also uses an object (of type Colour) which represents some allocation strategy for the reified object; it simulates some mapping strategy, e.g. in the case of the creation of a remote object.

5.1.1 Reified class

The first thing is to declare a reified class, inheriting from EC_Reflect; the user will just inherit from that class in order to get the desired behaviour.

namespace EC
{
	class Echo: public EC_Reflect
	{
	 public:
		void* operator new (size_t s, Colour m);
	 protected:
		Echo_P* ec_proxy();
	} ;
}

The Echo_P class, a proxy class, implements the printing behaviour. The allocator new allows for passing the mapping parameter. Now, all classes that will inherit from Echo will be automatically given the corresponding proxy, and as such, its behaviour.

5.1.2 Proxy definition

The second thing to define, as a library programmer, is the proxy class that implements the behaviour:

namespace EC
{
	class Echo_P : public EC_Proxy
	{
	 public:
		EC_Any obj; // Reified object
		Colour mapping; // Some allocation or mapping value
		void ec_reify (EC_Call* c)
		{
			cout << c->mb->name() << endl; // print out the name
			c->res=c->execute(obj); // do the call
		}
		// Constructor
		Echo_P (Colour m, EC_Class cl, EC_Call* c)
		{
			mapping = m;
			obj = cl.new_obj(c); // Create the reified object
		}
	} ;
}

The class holds a reference to the object for which it acts as a proxy (obj). The attribute mapping (type Colour) holds the mapping value. The routine ec_reify programs the desired behaviour:

Finally, the constructor routine receives as a first parameter the allocator parameter (of type Colour, not really used in that example), and then the type of the actual object being created (EC_Call), and the reification of the constructor (EC_Class). The routine just creates the object, and assigns it to the obj attribute of the proxy in order to keep a reference to it.

5.1.3 Using the reified class

Let us say we have a typical user class of the form:

class C
{ // Any user class
public:
	Res* foo ( param );
	virtual Res* vfoo ( param );
	// Constructors
	C(P1 pl);
	C(P1 p2);
}

If a final user needs to add the echo behaviour to this class, he will only need to declare the following:

class Cecho : public C, public Echo
{
public:
	Cecho(P1 pl): C(pl)
	Cecho(P1 p2): C(p2)
}:

Then the class Cecho can be used directly:

void main()
{
	P1 pl;
	Colour green;
	Cecho* ce = ec_new ((green), Cecho, (pl));
	r = ce->vfoo(...);
	r = ce->foo (...);
}

Both functions will present the echo behaviour. If one needs to use the Cecho class in an existing application, it can be done through polymorphism between entities of type C and Cecho:

void main()
{
	P1 pl;
	Colour green;
	C* c;
	Cecho* ce = ec_new ((green), Cecho, (pl));
	c = ce; // Polymorphic assignment
	r = c->vfoo(...);
}

Of course in this case, due to the dynamic binding that occurs only on virtual functions in C++, the echo behaviour will occur only on those functions declared virtual in C.


Copyright 1997 EUROPA WG

Last updated: 26 Nov 1997