/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/*
			 Orientation Object:
			---------------------
*/
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

// Precaution pour eviter les inclusions en double.

#ifndef		_DefQuatreClasse
#define		_DefQuatreClasse
/* -------------------------------------------------------------------- */

#include	<stdio.h>
#include	<stdlib.h>

typedef	struct	_QuatreClasse
	{
	// Membre methode.
	int	(* getDd)(struct _QuatreClasse *);	
			// parametrage non verifie !

	// Membre donnee (attribut)
	int	dd;
	}
	QuatreClasse;

// Constructeur.
QuatreClasse *	newQuatreClasse		()
	;

// Destructeur.
void		destroyQuatreClasse	(QuatreClasse * this)
	;

// Fonction independante (#'static' en Java)
void		any4			()
	;
	
/* -------------------------------------------------------------------- */
#endif
	
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/*
			--------------------
			 Orientation Objet:
			--------------------
*/
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

//	'Prototype' de la classe.

#include	<QuatreClasse.h>

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

//	Fonction publique.
//	Au lieu de 'any4', on peut employer 'QuatreClasse_any4',
//		pour eviter les collisions de noms.

void		any4			()
	{
	printf	("any4\n");
	}

//	Fonction privee.
//	Utilisee ici pour l'accesseur de l'attribut 'dd' (cf constructeur)

static
int		QuatreClasse_getDd	(QuatreClasse * this)
	{
	printf	("QuatreClasse_getDd\n");
	return	this->dd;
	}

//	Constructeur.
//	On pourait en avoir plusieurs, mais il faudrait les numeroter
//		'newQuatreClasse1', 'newQuatreClasse2'...

QuatreClasse *	newQuatreClasse		(/* ... */)
	{
	// Allocation de la place necessaire.
	QuatreClasse *	ret	= (QuatreClasse *)malloc(sizeof(QuatreClasse));

	// Initialisation des pointeurs de fonction.
	ret->getDd		= QuatreClasse_getDd;

	// Renvoi du pointeur sur l'objet construit.
	return	ret;
	}

//	Destructeur;

void		destroyQuatreClasse	(QuatreClasse * this)
	{
	// Destruction des membres.
	// ...
	
	// Destruction, pour finir, de l'objet.
	free	(this);
	}

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */


/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/*
		-------------------------
		 Pre Etude des Objets...
		-------------------------
*/
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

#include	<stdio.h>
#include	<malloc.h>

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

#ifndef		_DefInterface1
#define		_DefInterface1
/* -------------------------------------------------------------------- */

typedef	struct	_Interface1
	{
	void	(* pfa)();
	void	(* pfb)();
	}
	Interface1;
	
/* -------------------------------------------------------------------- */
#endif

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

#ifndef		_DefInterface2
#define		_DefInterface2
/* -------------------------------------------------------------------- */

typedef	struct	_Interface2
	{
	void	(* pfc)();
	void	(* pfd)();
	}
	Interface2;
	
/* -------------------------------------------------------------------- */
#endif

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

#ifndef		_DefImplementation
#define		_DefImplementation
/* -------------------------------------------------------------------- */


typedef	struct	_Implementation
	{
	Interface1 *	theInterface1;
	Interface2 *	theInterface2;
	}
	Implementation;

static
void			myFonctionA		()
	{
	printf	("myFonctionA()\n");
	}

static
void			myFonctionB		()
	{
	printf	("myFonctionB()\n");
	}

static
void			myFonctionC		()
	{
	printf	("myFonctionC()\n");
	}

static
void			myFonctionD		()
	{
	printf	("myFonctionD()\n");
	}

Implementation *	newImplementation	(/* ... */)
	{
	// construction par morceaux

	Interface1 *		z1;
	Interface2 *		z2;
	Implementation *	q;
	
	z1	= (Interface1 *)	malloc(sizeof(Interface1));
	z2	= (Interface2 *)	malloc(sizeof(Interface2));
	q	= (Implementation *)	malloc(sizeof(Implementation));
	
	// realisations choisies d'implementations
	// (c'est a dire, fonctions virtuelles)

	z1->pfa	=	myFonctionA;
	z1->pfb	=	myFonctionB;
	z2->pfc	=	myFonctionC;
	z2->pfd	=	myFonctionD;
	
	q->theInterface1 = z1;
	return	q;
	/* ... */
	}

void			destroyImplementation	(Implementation * p)
	{
	/* ... */
	//free	(p->theInterface1); // surtout pas ! (pas alloue !)
	free	(p);
	}

/* -------------------------------------------------------------------- */
#endif

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

/**
 *	Procedure principale.
 */
int		main			(int argc, char * argv[])
	{
	int	w, rc;

	printf	("\n");
	printf	("--------------------\n");
	printf	(" Orientation Objet: \n");
	printf	("--------------------\n");
	printf	("\nB.M.G. version Ete 2010:\n");
	printf	("\nligne de commande:\n");
	for	(w = 0; w < argc; w++)
		{
		printf	("\t%d\t%s\n", w, argv[w]);
		}
	printf	("\n");
	
	Implementation *	z	= newImplementation();
	
	(z->theInterface1->pfa)();
	(z->theInterface1->pfb)();
	(z->theInterface2->pfc)();
	(z->theInterface2->pfd)();
	
	destroyImplementation	(z);
	
	return	0;
	}

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

