Je souhaite me connecter à une base de données.
Or, les bibliothèques ne sont pas les mêmes selon les bases de données.
Donc je souhaite définir un ensemble de services qui devront me permettre de faire tout ce dont j'ai besoin sur ma base de données. J'ai pensé représenter ces différents services avec un ensemble de classes dont les méthodes sont toutes virtuelles pures.
L'accès aux données sera donc codé différemment selon les moteurs de bases de données (PostgreSQL, MySQL, etc), mais devra par contre _toujours_ utiliser l'interface commune définie précédemment. En effet, grâce à une factorisation de toutes les instanciations des classes spécifiques aux BDD, le changement du moteur de base de données ne devrait donner lieu à aucun changement dans le code source qui utilise l'interface.
ex :
on définit une interface Connection qui doit permettre, entre autres, d'effectuer des requêtes :
class Connection
{
public:
virtual Resultat executeQuery( string requete ) = 0 ;
}
Ensuite, comme on a décidé d'utiliser MySQL (par exemple), on implémente l'interface Connection avec un accès spécifique à MySQL
class MySQL_Connection
: public Connection
{
Resultat executeQuery( string requete )
{
/* fait son travail */
}
}
Du coup, on peut utiliser MySQL_Connection comme une instance de Connection :
Connection* c= new MySQL_Connection ;
//[...]
Resulat r= c->executeQuery("SELECT * FROM TABLE") ;
r.doSomething()
//[...]
On est bien d'accord que, dans le cas où on souhaite passer à PostgreSQL, le seul truc à changer dans le source est la ligne concernant la création de Connection :
Connection* c= new PostgreSQL_Connection ;
//=> le reste ne change pas.
Bref, tout cela fonctionne, le problème c'est que lorsque j'ai besoin de définir une Connection particulière au niveau de mes interfaces :
class SpecialConnection
: public Connection
{
public:
virtual void doSomethingSpecial() = 0 ;
}
Dans l'idée, mon implémentation de SpecialConnection (si je me ramène dans le cas ou je travaillais avec MySQL) ressemblerait à ceci :
class MySQL_SpecialConnection
: public SpecialConnection
{
Resultat executeQuery( string requete )
{
/* fait son travail */
}
void doSomethingSpecial()
{
/* fait quelque chose de spécial */
}
}
Mais alors du coup ça m'oblige à copier coller toutes mes méthodes déjà implémentées dans MySQL_Connection dans le source de MySQL_SpecialConnection... C'est pour ça que le plus logique serait de faire ceci :
class MySQL_SpecialConnection
: public SpecialConnection, MySQL_Connection
{
void doSomethingSpecial()
{
/* fait quelque chose de spécial */
}
}
Le problème est que cette tentative d'héritage multiple ne fonctionne pas...

(j'espère que c'est un peu plus clair)