1


Salut,

je souhaite faire en sorte d'abstraire l'accès à une base de données en C++, donc je passe par des classes virtuelles pures qui me fournissent une interface du type :
DriverManager.getConnection(), Connection.createStatement(), Statement.executeQuery(), etc...



En Java, je saurais faire ça sans problèmes, mais j'avoue que j'ai un peu de mal avec le C++ (ça fait bien longtemps que je n'en ai plus fait...).
Bref, pour simplifier tout ça, j'ai fait un petit exemple simple en Java avec des Fruits/Pommes etc...


Voici l'implémentation en Java, qui fonctionne :

Les interfaces Java :

public interface Fruit
{
	Infos getInfos() ;
}


public interface Infos
{
	void print() ;
}





L'implémentatin Java :

public class Pomme
	implements Fruit
{
	public Infos getInfos()
	{
		return new InfosPomme() ;
	}
}



public class InfosPomme
	implements Infos
{
	public void print()
	{
		System.out.println("InfosPomme.print()") ;
	}
}



Et le main java :

public class Main
{
	/**
	 * @param args
	 */
	public static void main( String[] args )
	{
		Fruit f= new Pomme() ;
		Infos i= f.getInfos() ;
		i.print() ;
	}
}


Qui affiche, comme on pouvait s'y attendre :
InfosPomme.print()



2

En C++, voici ce que j'ai codé :


Les interface (classes virtuelles pures) C++ :
// Fruit.h: interface for the Fruit class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FRUIT_H__8E01E81D_85AC_4033_97B0_D8E96E3ACD77__INCLUDED_)
#define AFX_FRUIT_H__8E01E81D_85AC_4033_97B0_D8E96E3ACD77__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Infos.h"

class Fruit  
{
public:
	Fruit() ;
	virtual ~Fruit()= 0 ;

	virtual Infos& getInfos()= 0 ;
};

#endif // !defined(AFX_FRUIT_H__8E01E81D_85AC_4033_97B0_D8E96E3ACD77__INCLUDED_)




// Infos.h: interface for the Infos class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_INFOS_H__D255DD66_031F_4F9A_BD12_10387F5DDD05__INCLUDED_)
#define AFX_INFOS_H__D255DD66_031F_4F9A_BD12_10387F5DDD05__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class Infos  
{
public:
	Infos();
	virtual ~Infos()= 0;
	virtual void print()= 0 ;
};

#endif // !defined(AFX_INFOS_H__D255DD66_031F_4F9A_BD12_10387F5DDD05__INCLUDED_)





L'implémentation C++ :

// Pomme.h: interface for the Pomme class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_POMME_H__DDE1E38C_7ABE_4593_AC41_BF3DE71C99E7__INCLUDED_)
#define AFX_POMME_H__DDE1E38C_7ABE_4593_AC41_BF3DE71C99E7__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Fruit.h"

class Pomme : public Fruit  
{
public:
	Pomme();
	virtual ~Pomme();
	Infos& getInfos() ;
};

#endif // !defined(AFX_POMME_H__DDE1E38C_7ABE_4593_AC41_BF3DE71C99E7__INCLUDED_)



// Pomme.cpp: implementation of the Pomme class.
//
//////////////////////////////////////////////////////////////////////

#include "Pomme.h"
#include "InfosPomme.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Pomme::Pomme()
{

}

Pomme::~Pomme()
{

}

Infos& Pomme::getInfos()
{
	Infos* i= new InfosPomme ;
	return *i ;
}







// InfosPomme.h: interface for the InfosPomme class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_INFOSPOMME_H__8683B825_FD15_4520_99A3_2517DAF3D87E__INCLUDED_)
#define AFX_INFOSPOMME_H__8683B825_FD15_4520_99A3_2517DAF3D87E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Infos.h"

class InfosPomme : public Infos  
{
public:
	InfosPomme();
	virtual ~InfosPomme();
	void print() ;
};

#endif // !defined(AFX_INFOSPOMME_H__8683B825_FD15_4520_99A3_2517DAF3D87E__INCLUDED_)



// InfosPomme.cpp: implementation of the InfosPomme class.
//
//////////////////////////////////////////////////////////////////////

#include <iostream>
#include <string>
#include "InfosPomme.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

InfosPomme::InfosPomme()
{

}

InfosPomme::~InfosPomme()
{

}


void InfosPomme::print()
{
	std::cout << "infosPomme" << std::endl ;
}




Et le main C++ :


#include "Pomme.h"
#include "InfosPomme.h"

int main( int argc, char* argv[] )
{
	Fruit* p= new Pomme ;
	Infos i= p->getInfos() ;
	i.print() ;
	return 0 ;
}




mais ça ne fonctionne pas sad

Voici les erreurs de compilation :
Deleting intermediate files and output files for project 'TestCase - Win32 Debug'.
--------------------Configuration: TestCase - Win32 Debug--------------------
Compiling...
Fruit.cpp
Pomme.cpp
Infos.cpp
InfosPomme.cpp
main.cpp
c:\3dsmax6\maxsdk\samples\testcase\main.cpp(10) : error C2259: 'Infos' : cannot instantiate abstract class due to following members:
        c:\3dsmax6\maxsdk\samples\testcase\infos.h(13) : see declaration of 'Infos'
c:\3dsmax6\maxsdk\samples\testcase\main.cpp(10) : warning C4259: '__thiscall Infos::~Infos(void)' : pure virtual function was not defined
        c:\3dsmax6\maxsdk\samples\testcase\infos.h(16) : see declaration of 'Infos::~Infos'
c:\3dsmax6\maxsdk\samples\testcase\main.cpp(10) : warning C4259: 'void __thiscall Infos::print(void)' : pure virtual function was not defined
        c:\3dsmax6\maxsdk\samples\testcase\infos.h(17) : see declaration of 'print'
c:\3dsmax6\maxsdk\samples\testcase\main.cpp(10) : error C2259: 'Infos' : cannot instantiate abstract class due to following members:
        c:\3dsmax6\maxsdk\samples\testcase\infos.h(13) : see declaration of 'Infos'
c:\3dsmax6\maxsdk\samples\testcase\main.cpp(10) : warning C4259: '__thiscall Infos::~Infos(void)' : pure virtual function was not defined
        c:\3dsmax6\maxsdk\samples\testcase\infos.h(16) : see declaration of 'Infos::~Infos'
c:\3dsmax6\maxsdk\samples\testcase\main.cpp(10) : warning C4259: 'void __thiscall Infos::print(void)' : pure virtual function was not defined
        c:\3dsmax6\maxsdk\samples\testcase\infos.h(17) : see declaration of 'print'
Error executing cl.exe.
Creating browse info file...

TestCase.exe - 2 error(s), 4 warning(s)

3

Donc bon, si vous voyez ce qui ne va pas... merci d'avance wink

4

Pour tes erreurs, c'est juste que tu ne peux pas instancier "Infos i" dans ton main puisque c'est une classe abstraite, il faudrait faire "Infos& i" pour avoir une réference (une variable de type "Infos" en Java est automatiquement un pointeur vers un objet, alors qu'en C++ c'est un objet).

Sinon il y a quelque chose qui me semble discutable, c'est le "Infos* i= new InfosPomme ; return *i ;" (tu pourrais directement faire "return *new InfosPomme" d'ailleurs) tu n'es plus en Java, et il n'y a pas de garbage collector qui va aller libérer ta variable une fois non utilisée; si tu retournes "*i", tu vas sans doute utiliser "i" comme une variable tout à fait quelconque puis l'oublier une fois les traitements terminés => leak. Perso j'aurais tendance à faire retourner un pointeur à "getInfos", pour pouvoir le delete plus tard, mais bon avec ton truc tu pourras quand même faire un "delete &i" dans ton main après le "i.print", donc à toi de voir ce qui te semble le plus élégant, c'est juste une question de goût et je laisse les adeptes de ce genre de trolls discuter de ce qui est le "mieux" tongue
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

5

Zephyr (./4) :
Pour tes erreurs, c'est juste que tu ne peux pas instancier "Infos i" dans ton main puisque c'est une classe abstraite, il faudrait faire "Infos&amp; i" pour avoir une réference (une variable de type "Infos" en Java est automatiquement un pointeur vers un objet, alors qu'en C c'est un objet).


ah ben oui, quel boulet (d'ailleurs je renvoie bien une référence...)
merci bisoo

Zephyr (./4) :
Sinon il y a quelque chose qui me semble discutable, c'est le "Infos* i= new InfosPomme ; return *i ;" (tu pourrais directement faire "return *new InfosPomme" d'ailleurs) tu n'es plus en Java, et il n'y a pas de garbage collector qui va aller libérer ta variable une fois non utilisée; si tu retournes "*i", tu vas sans doute utiliser "i" comme une variable tout à fait quelconque puis l'oublier une fois les traitements terminés => leak. Perso j'aurais tendance à faire retourner un pointeur à "getInfos", pour pouvoir le delete plus tard, mais bon avec ton truc tu pourras quand même faire un "delete &amp;i" dans ton main après le "i.print", donc à toi de voir ce qui te semble le plus élégant.

oui oui, je me suis rendu compte du problème tout à l'heure, mais merci de soulever le problème smile (et tu avais raison, c'est pas juste discutable, c'est laid hehe)
Je pense que je vais renvoyer un pointeur, c'est plus transparent je trouve.

6

mais non ce qui serait plus transparent ce serait de supprimer le post initial cheekytriso

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

7

trisotfl