Par curiosité, vous pouvez lire le sujet précédent
Interface dont l'implémentation est réparti dans plusieurs classes

Voici encore un petit problème avec les Interfaces !
Je précise qu'il n'est pas volontaire, j'ai décomposé une interface en deux interfaces, mais j'ai oublié de retirer l'une fonction déportée, j'avais donc deux fois la même méthode abstraite, ce qui je pense n'a pas de sens !

Voici un Exemple

Deux interfaces, héritage de l'une à l'autre !
A() est commune aux deux !
Pour moi, c'est une Erreur de Conception, dommage que le compilateur ne râle pas

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//---------------------------------------------------------------------------
class IFirstInterface
{
public:
  virtual int A() = 0;
  virtual int B() = 0;
};
 
class IFirstExtendedInterface: public IFirstInterface
{
public:
  virtual int A() = 0; // en double puisque déjà dans IFirstInterface
  virtual int E() = 0;
  virtual int F() = 0;
};
Implémentation en Style C++
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
class CFirstExtended: public IFirstExtendedInterface
{
public:
  int A() {return 1111111;}
  int B() {return 2222222;}
  int E() {return 5555555;}
  int F() {return 6666666;}
};
Implémentation en Style Delphi VCL

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
class TFirstExtended: public TObject, public IFirstExtendedInterface
{
public:
  int A() {return -1111111;}
  int B() {return -2222222;}
  int E() {return -5555555;}
  int F() {return -6666666;}
};
Petit Code de Test

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  MemoTrace->Lines->Add("C++ Pur A, B, E et F");
  CFirstExtended* ObjCFE1 = new CFirstExtended();
  IFirstInterface* ICF1 = ObjCFE1;
  IFirstExtendedInterface* ICFE1 = ObjCFE1;
  MemoTrace->Lines->Add(Format("A : %d - B : %d - E : %d - F : %d", ARRAYOFCONST((ICF1->A(), ICF1->B(), ICFE1->E(), ICFE1->F()))));
  delete ObjCFE1;
 
  AnsiString CatchMessage;
  MemoTrace->Lines->Add("TObject A, B, E et F");
  try
  {
    CatchMessage = "new";
    TFirstExtended* ObjVCLFE1 = new TFirstExtended();
    IFirstInterface* IVCLF1 = ObjVCLFE1;
    IFirstExtendedInterface* IVCLFE1 = ObjVCLFE1;
    CatchMessage = "call";
    MemoTrace->Lines->Add(Format("A : %d - B : %d - E : %d - F : %d", ARRAYOFCONST((IVCLF1->A(), IVCLF1->B(), IVCLFE1->E(), IVCLFE1->F()))));
    delete ObjVCLFE1;
  }
  catch(const EAccessViolation &e)
  {
    MemoTrace->Lines->Add("EAccessViolation - " +  e.Message + " : " + CatchMessage);
  }
  catch (Exception &exception)
  {
    MemoTrace->Lines->Add("Unexpected Exception - " +  exception.Message + " : " + CatchMessage);
  }
  catch(...)
  {
    MemoTrace->Lines->Add("Undefined : " + CatchMessage);
  }
C++Builder 2007, j'obtiens

C++ Pur A, B, E et F
A : 1111111 - B : 2222222 - E : 5555555 - F : 6666666
TObject A, B, E et F
EAccessViolation - EAccessViolation : new
C++Builder XE, j'obtiens
C++ Pur A, B, E et F
A : 1111111 - B : 2222222 - E : 5555555 - F : 6666666
TObject A, B, E et F
Undefined : new
vous noterez que les objets C++ encore une fois résiste à tous les problèmes lié à l'héritage d'interface !
Pour les objets VCL, c'est la catastrophe, dans le précédent sujet, c'était l'appel de fonction qui provoquait une EAbstractError, et bien là c'est directement le new qui provoque une EAccessViolation probablement quelque part dans la VMT, je suppose !

Sinon mon XE semble fatigué, mes Exceptions VCL ne fonctionne pas !