Recent

Author Topic: [SOLVED] specialize doesn't take care about abstract methods...  (Read 2149 times)

gelinp

  • Full Member
  • ***
  • Posts: 114
[SOLVED] specialize doesn't take care about abstract methods...
« on: February 07, 2016, 10:42:28 am »
Hi,

I defined a generic type with virtual abstract methods. When I use specialize with my DAO<T> generic in daoplanclssement unit then the compilator display error message to ask I define virtual abstracts methods... It's like specialized type erase virtual abstract definission signature ! This errors messages and full code (2 units DAO and daoplanclassement. I marked the problem into daoplanclassement unit with the message "************* THIS 2 LIGNES ARE THE PROBLEM ****************************".

Errors messages
Code: Pascal  [Select][+][-]
  1. Compilation du projet, Mode : Linux - Cible : typodoc : Code de sortie 1 - Erreurs : 4
  2. daoplanclassement.pas(26,14) Error: Forward declaration not solved "IDAO$TRecordPlanClassement.Instancier(const LongInt):<record type>;"
  3. daoplanclassement.pas(28,14) Error: Forward declaration not solved "IDAO$TRecordPlanClassement.Ajouter(const TRecordPlanClassement):<record type>;"
  4. daoplanclassement.pas(30,15) Error: Forward declaration not solved "IDAO$TRecordPlanClassement.Sauvegarder(const TRecordPlanClassement);"
  5. daoplanclassement.pas(32,15) Error: Forward declaration not solved "IDAO$TRecordPlanClassement.Supprimer(TRecordPlanClassement);"
  6.  

DAO unit
Code: Pascal  [Select][+][-]
  1. unit DAO;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, databasemanager;
  9.  
  10. type
  11.   // **************************************************************
  12.   // 4. IDAO<T>
  13.   // INTERFACE DATA ACCESS OBJECT
  14.  
  15.   // Classe DAO pour gérer la persistance d'une classe <T> en gérant
  16.   // son actualisation en base de donnée, et son instanciation dans
  17.   // un modèle observé par des observateurs.
  18.   // **************************************************************
  19.   generic IDAO<T> = class
  20.     // T : le typde d'objet gérer par le DAO
  21.   private
  22.     _dbm: IDatabaseManager;
  23.   public
  24.     constructor Create(databaseManager: IDatabaseManager);
  25.     // Lire un objet T existant
  26.     function Instancier(const id: integer): T; virtual; abstract;
  27.     // Ajoute un nouvel objet T
  28.     function Ajouter(const obj: T): T; virtual; abstract;
  29.     // Mémoriser un objet T
  30.     procedure Sauvegarder(const obj: T); virtual; abstract;
  31.     // Supprimer un objet T
  32.     procedure Supprimer(obj: T); virtual; abstract;
  33.   end;
  34.  
  35.  
  36. implementation
  37.  
  38.  
  39. // **************************************************************
  40. // IDAO<T>
  41. // INTERFACE DATA ACCESS OBJECT
  42. // **************************************************************
  43. constructor IDAO.Create(databaseManager: IDatabaseManager);
  44. begin
  45.   _dbm := databaseManager;
  46. end;
  47.  
  48. end.

daoplanclassement unit
Code: Pascal  [Select][+][-]
  1.  unit daoplanclassement;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, DB, databasemanager, DAO;
  9.  
  10. type
  11.   /////////////////////////////////////////////////////////////////////
  12.   // TRecordPlanClassement
  13.   /////////////////////////////////////////////////////////////////////
  14.   TRecordPlanClassement = record
  15.     PKPlan: integer;  // La clé primaire du plan de classement
  16.     Libelle: string;  // Le libellé du plan de classement
  17.   end;
  18.  
  19.   ////////////////////////////////////////////////////////
  20.   // TDAORecordPlanClassement
  21.   ////////////////////////////////////////////////////////
  22.   // Un plan de classement est défini dans le SGBD dans la table spécifiées
  23.   // ci-dessous (les classes du plan de classement sont dans la table
  24.   // DocLesPlansClasses ):
  25.   //
  26.   // CREATE TABLE "docLesPlansClassement" (
  27.   //        "PKplan" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL ,
  28.   //        "NomPlan," CHAR(100) UNIQUE )
  29.   //
  30.   // Remarque : Dans cette version les champs left et right ne sont pas utilisés
  31.   // (méthode des 'data set', car j'utiliseplutôt l'exploitation des indices
  32.   // décimaux de classes et leur traitement sous simple chaine de caractère. Il
  33.   // est possible de rechercher les descendants par comparaison du début de
  34.   // l'indice et de retrouver le chemin qui mène à l'ancêtre par lecture de
  35.   // l'indice courant.
  36.  
  37. ************* THIS 2 LIGNES ARE THE PROBLEM ****************************
  38.  IDAORecordPlanClassement = specialize IDAO<TRecordPlanClassement>;
  39.  
  40.   TDAOPlanClassement = class(IDAORecordPlanClassement)
  41.   private
  42.     _PKPlan: integer;
  43.     _Libelle: string;
  44.   public
  45.     // La collection des plans de classement
  46.     procedure AttacheDataSourceLesPlansClassements(DataSource: TDataSource);
  47.     // Attacher une DataSource à la collection des classes du plan de classement
  48.     procedure AttacheDataSourceLesClasses(DataSource: TDataSource);
  49.     // Détache une DataSource
  50.     procedure DetacheDataSource(DataSource: TDataSource);
  51.  
  52.     // La clé primaire du plan de classement s'il existe
  53.     function Existe(NomPlan: string): integer;
  54.  
  55.     // Lire un objet TRecordPlanClassement existant
  56.     function Instancier(const id: integer): TRecordPlanClassement; override;
  57.     // Ajoute un nouvel objet TRecordPlanClassement
  58.     function Ajouter(const obj: TRecordPlanClassement): TRecordPlanClassement; override;
  59.     // Mémoriser un objet TRecordPlanClassement
  60.     procedure Sauvegarder(const obj: TRecordPlanClassement); override;
  61.     // Supprimer un objet TRecordPlanClassement
  62.     procedure Supprimer(obj: TRecordPlanClassement); override;
  63.   end;
  64.  
  65. implementation
  66. /////////////////////////////////////////////////////////////////////////////
  67.  
  68.  
  69. //           TDAOPlanClassement
  70.  
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73. // -----------------------------------------------------------------------------
  74. // Classe :  TDAOPlanClassement
  75. // Méthode : AttacheDataSourceLesPlansClassements (procedure)
  76. // Parametres
  77.  
  78. // La collection des noms de plans de classement.
  79. // -----------------------------------------------------------------------------
  80. procedure TDAOPlanClassement.AttacheDataSourceLesPlansClassements(
  81.   DataSource: TDataSource);
  82. var
  83.   hsql: IRequeteSQL;
  84. begin
  85.   hsql := _dbm.LaRequete('PLAN_CLASSEMENT_COLLECTION');
  86.   hsql.Execute;
  87.   hsql.AttacherDataSourceCible(DataSource);
  88. end;
  89.  
  90. // -----------------------------------------------------------------------------
  91. // Classe :  TDAORecordPlanClassement
  92. // Méthode : AttacheDataSourceLesClasses (procedure)
  93. // Parametres
  94. // FKPlan       Integer          La liste des classes d'un plan
  95.  
  96. // La collection des classes instanciée correspondant au plan de classement
  97. // passé en paramètre.
  98. // -----------------------------------------------------------------------------
  99. procedure TDAOPlanClassement.AttacheDataSourceLesClasses(DataSource: TDataSource);
  100. var
  101.   hsql: IRequeteSQL;
  102. begin
  103.   hsql := _dbm.LaRequete('PLAN_CLASSE_COLLECTION');
  104.   hsql.ParamByName('FKPlan', _PKPlan);
  105.   hsql.Execute;
  106.   hsql.AttacherDataSourceCible(DataSource);
  107. end;
  108.  
  109. // -----------------------------------------------------------------------------
  110. // Classe :  TDAOPlanClassement
  111. // Méthode : Existe (class function)
  112. // Parametres
  113. // PKPlan si le plan de classement du nom entré en paramètre existe, sinon -1.
  114. // -----------------------------------------------------------------------------
  115. function TDAOPlanClassement.Existe(NomPlan: string): integer;
  116. var
  117.   hsql: IRequeteSQL;
  118. begin
  119.   try
  120.     hsql := _dbm.LaRequete('PLAN_CLASSEMENT_EXISTE');
  121.     hsql.ParamByName('NomPlan', NomPlan);
  122.  
  123.     if hsql.NombreLignes = 1 then
  124.       Result := hsql.ValueByName('PKPlan')
  125.     else
  126.       Result := 0;
  127.   except
  128.     Result := 0;
  129.   end;
  130. end;
  131.  
  132. // -----------------------------------------------------------------------------
  133. // Classe : TDAOPlanClassement
  134. // Methode : Ajouter (fonction)
  135. // Parametre
  136. // obj          TRecordPlanClassement         Le nouveau plan de classement
  137.  
  138. // Ajoute un nouveau plan de classement à la base (pas les classes, seulement le
  139. // nom du nouveau plan de classement. (Les classes seront ajoutées une à une au
  140. // moment de leur création par la méthode ajouterClasse de la classe
  141. // TPlanClassement).
  142. // -----------------------------------------------------------------------------
  143. function TDAOPlanClassement.Ajouter(
  144.   const obj: TRecordPlanClassement): TRecordPlanClassement;
  145. var
  146.   hsql: IRequeteSQL;
  147. begin
  148.   try
  149.     // Ajout du nouveau plan dans la table docLesPlansClassement
  150.     hsql := _dbm.LaRequete('PLAN_CLASSEMENT_AJOUTER');
  151.     hsql.ParamByName('NomPlan', obj.Libelle);
  152.     hsql.Execute;
  153.     // Actualisation de la nouvelle clé du plan créé par la base de données
  154.     Result.PKPlan := hsql.ValueByName('PKPlan');
  155.     Result.Libelle := hsql.ValueByName('Libelle');
  156.     _PKplan  := hsql.ValueByName('PKPlan');
  157.     _Libelle := hsql.ValueByName('NomPlan');
  158.   except
  159.     Result.PKPlan  := -1;
  160.     Result.Libelle := '';
  161.   end;
  162. end;
  163.  
  164. // -----------------------------------------------------------------------------
  165. // Classe : TDAOPlanClassement
  166. // Méthode : Instancier (function)
  167. // Parametres
  168. // id        Integer          La clé primaire du plan
  169. // Resultat    TRecordPlanClassement
  170. // Description
  171. // Le plan de classement instancié en une fois (sans pagination)
  172. // -----------------------------------------------------------------------------
  173. function TDAOPlanClassement.Instancier(const id: integer): TRecordPlanClassement;
  174. var
  175.   hsql: IRequeteSQL;
  176. begin
  177.   try
  178.     // Verification que la plan existe
  179.     hsql := _dbm.LaRequete('PLAN_CLASSEMENT_INSTANCIER');
  180.     hsql.ParamByName('PKplan', id);
  181.     hsql.Execute;
  182.     // Instanciation des paramètres du plan
  183.     Result.PKPlan := hsql.ValueByName('PKPlan');
  184.     Result.Libelle := hsql.ValueByName('NomPlan');
  185.     _PKplan  := hsql.ValueByName('PKPlan');
  186.     _Libelle := hsql.ValueByName('NomPlan');
  187.   except
  188.     Result.PKPlan  := -1;
  189.     Result.Libelle := '';
  190.   end;
  191. end;
  192.  
  193. // -----------------------------------------------------------------------------
  194. // Classe : TDAOPlanClassement
  195. // Méthode Sauvegarder (procedure)
  196.  
  197. // Parametres
  198. // obj       TRecordPlanClassement     Le plan de classement à sauvegarder dans la base
  199. // -----------------------------------------------------------------------------
  200. procedure TDAOPlanClassement.Sauvegarder(const obj: TRecordPlanClassement);
  201. var
  202.   hsql: IRequeteSQL;
  203. begin
  204.   // Sauvegarde du nouveau nom du plan de classement
  205.   hsql := _dbm.LaRequete('PLAN_CLASSEMENT_SAUVEGARDER');
  206.   hsql.ParamByName('PKPlan', obj.PKPlan);
  207.   hsql.ParamByName('NomPlan', obj.Libelle);
  208.   hsql.Execute;
  209. end;
  210.  
  211. // -----------------------------------------------------------------------------
  212. // Classe : TDAOPlanClassement
  213. // Méthode Supprimer (procedure)
  214.  
  215. // Parametres
  216. // obj       TRecordPlanClassement     Le plan de classement à sauvegarder dans la base
  217. // -----------------------------------------------------------------------------
  218. procedure TDAOPlanClassement.Supprimer(obj: TRecordPlanClassement);
  219. var
  220.   hsql: IRequeteSQL;
  221. begin
  222.   // Suppression d'un plan de classement (les classes associées au plan ne
  223.   // sont pas supprimée).
  224.   hsql := _dbm.LaRequete('PLAN_CLASSEMENT_SUPPRIMER');
  225.   hsql.ParamByName('PKPlan', obj.PKPlan);
  226.   hsql.Execute;
  227.   _PKplan  := 0;
  228.   _Libelle := '';
  229. end;
  230.  
  231. end.  
« Last Edit: February 07, 2016, 02:29:00 pm by gelinp »
My configuration is : Lazarus 1.6+dfsg-1 / FPC 3.0.0 / Debian Mint / x86_64-linux-gtk2

guest58172

  • Guest
Re: specialize doesn't take care about abstract methods...
« Reply #1 on: February 07, 2016, 01:58:44 pm »
I bet you use FPC 2.6.4.

You code will work fine with FPC 3.0.0. For example the following reduction of the case compiles without error with FPC 3.0.0:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}{$H+}
  3. type
  4.   generic TFoo<T> = class
  5.     function foo: T; virtual; abstract;
  6.   end;
  7.  
  8.   TRec = record
  9.     field: integer;
  10.   end;
  11.  
  12.   TInter = specialize TFoo<TRec>;
  13.   TBar = class(TInter)
  14.     function foo: TRec; override;
  15.   end;
  16.  
  17. function TBar.foo: TRec;
  18. begin
  19.   result.field := 0;
  20.   exit(result);
  21. end;
  22.  
  23. begin
  24. end.

but gives a similar error message with FPC 2.6.4, see online:
https://ideone.com/hndclm (unless they change the FPC version until you read this message).

Conclusion, use FPC 3.0.0

Thaddy

  • Hero Member
  • *****
  • Posts: 14393
  • Sensorship about opinions does not belong here.
Re: specialize doesn't take care about abstract methods...
« Reply #2 on: February 07, 2016, 02:13:32 pm »
Sigh, You are right. I do not sigh for though. But still there is a problem:


Can some moderator put a sticky on VERSIONS. And find a way of politely explaining to members that they are , well, STUPID and NOT READING DOCUMENTATION and plz tell them we... Oh well, sunday afternoon.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

gelinp

  • Full Member
  • ***
  • Posts: 114
Re: specialize doesn't take care about abstract methods...
« Reply #3 on: February 07, 2016, 02:18:44 pm »
Oups..., you are right, I forgeted to add my configuration  So now there is no problem any else because I added it to my signature, at footer ot each of my message...  :-[ !

Thank you very much for your response, so I'll try to install FPC 3.0 into my Lazarus 1.4.4...
« Last Edit: February 07, 2016, 02:23:29 pm by gelinp »
My configuration is : Lazarus 1.6+dfsg-1 / FPC 3.0.0 / Debian Mint / x86_64-linux-gtk2

Thaddy

  • Hero Member
  • *****
  • Posts: 14393
  • Sensorship about opinions does not belong here.
Re: specialize doesn't take care about abstract methods...
« Reply #4 on: February 07, 2016, 02:21:03 pm »
My configuration is : Lazarus 1.4.4 / FPC 2.6.4 / Linux Debian Lessy

Well, don't shout, but that is strange? Lessy?
And 2.6.4 is not supported. Because it is more like Nessy (are you from Scotland?)and very old...
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

guest58172

  • Guest
Re: specialize doesn't take care about abstract methods...
« Reply #5 on: February 07, 2016, 02:27:57 pm »
He's french, look at his code.

guest58172

  • Guest
Re: specialize doesn't take care about abstract methods...
« Reply #6 on: February 07, 2016, 06:01:04 pm »
My configuration is : Lazarus 1.4.4 / FPC 2.6.4 / Linux Debian Lessy

Well, don't shout, but that is strange? Lessy?
And 2.6.4 is not supported. Because it is more like Nessy (are you from Scotland?)and very old...

Also, next time you should think to reduce the problem. The database things, the comments, two units...were just some useless noise. As you have seen, the issue was reproducible in a dozen of  LOC.

 

TinyPortal © 2005-2018