[C++] Instanciation d1 classe abstraite oO !?
Fermé
Sir Bedevere
Messages postés
3
Date d'inscription
lundi 2 juin 2008
Statut
Membre
Dernière intervention
3 juin 2008
-
3 juin 2008 à 10:59
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 - 4 juin 2008 à 14:20
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 - 4 juin 2008 à 14:20
A voir également:
- [C++] Instanciation d1 classe abstraite oO !?
- Classe ram - Guide
- Comment savoir sa classe ✓ - Forum Loisirs / Divertissements
- Copain d'avant photo de classe - Forum Réseaux sociaux
- Retrouver photo de classe gratuitement - Forum Réseaux sociaux
- Bluetooth mercedes classe a 2005 - Forum Autoradio
8 réponses
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
3 juin 2008 à 11:42
3 juin 2008 à 11:42
Salut.
En effet, je suis perplexe aussi.
Que se passe t il si tu essai d'utliser A ? A.analyse(...)
Je ne comprends même pas pourquoi il compile.
si Analyseur<double> A(); fonctionne, il y a vraiment un problème. Quel est le compilateur ?
En effet, je suis perplexe aussi.
Que se passe t il si tu essai d'utliser A ? A.analyse(...)
Je ne comprends même pas pourquoi il compile.
si Analyseur<double> A(); fonctionne, il y a vraiment un problème. Quel est le compilateur ?
Sir Bedevere
Messages postés
3
Date d'inscription
lundi 2 juin 2008
Statut
Membre
Dernière intervention
3 juin 2008
3 juin 2008 à 14:44
3 juin 2008 à 14:44
Alors en effet, ce n'est pas "Analyseur A()" mais bien "Analyseur<double> A()" que j'ai mis dans mon programme et qui compilait.
Je viens de voir aussi que je n'avais pas mis le mot-clé "virtual" devant la déclaration d'analyse(). Une fois rajouté ce mot-clé, le compilo (c'est g++ 4.2 au fait) jette bien une erreur parce que j'essaie d'instanciser une classe abstraite. ouf !
Toutefois, l'instanciation d'une classe dérivée avec le constructeur par défaut fonctionne toujours, et je ne comprends pas pourquoi.
Je viens de voir aussi que je n'avais pas mis le mot-clé "virtual" devant la déclaration d'analyse(). Une fois rajouté ce mot-clé, le compilo (c'est g++ 4.2 au fait) jette bien une erreur parce que j'essaie d'instanciser une classe abstraite. ouf !
Toutefois, l'instanciation d'une classe dérivée avec le constructeur par défaut fonctionne toujours, et je ne comprends pas pourquoi.
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
3 juin 2008 à 15:22
3 juin 2008 à 15:22
Pour moi, ta class Analyseur est vide : elle est abstraite et ne contient aucune donnée membre. Il n'y a pas besoin d'un constructeur pour avoir une instance.
En lisant un cour d'assembleur, il parlai justement des notions de structure et de classe en C/C++.
Un structure (ou classe) est interprété par le compilateur comme une espèce de tableau avec des membres de taille variable. Les fonctions membre d'une classe, sont en fait des fonctions classiques avec un argument cacher :
type classA::fct(a,b) <=> type fct(classA&,a,b)
Donc, une class ne contenant que des fonctions, ne prend pas d'espace mémoire (enfin, c'est une image) donc n'a pas besoin de constructeur.
Mais ce n'est que mon avis, il faudrait vérifier dans les spécifications de l'ISO C++ et ne pas oublié que tout compilateur s'écarte un peu de ces spécifications, en particulier sur ces problèmes assez marginaux.
En lisant un cour d'assembleur, il parlai justement des notions de structure et de classe en C/C++.
Un structure (ou classe) est interprété par le compilateur comme une espèce de tableau avec des membres de taille variable. Les fonctions membre d'une classe, sont en fait des fonctions classiques avec un argument cacher :
type classA::fct(a,b) <=> type fct(classA&,a,b)
Donc, une class ne contenant que des fonctions, ne prend pas d'espace mémoire (enfin, c'est une image) donc n'a pas besoin de constructeur.
Mais ce n'est que mon avis, il faudrait vérifier dans les spécifications de l'ISO C++ et ne pas oublié que tout compilateur s'écarte un peu de ces spécifications, en particulier sur ces problèmes assez marginaux.
mamiemando
Messages postés
33077
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
18 avril 2024
7 748
3 juin 2008 à 16:10
3 juin 2008 à 16:10
A priori en C++ il faut implémenter un constructeur par défaut si celui-ci est explicitement appelé (par exemple les containers de la STL l'appellent explicitement).
De plus ce constructeur doit explicitement appeler les constructeurs des classes mères (ceci différencie le C++ du java, mais c'est grâce à ce genre de chose qu'on peut faire du multi-héritage en C++).
Exemple :
Donne :
Je te rappelle aussi que les membres de classes pouvant être initialisés avant l'accolade ouvrante du constructeur doivent l'être, et ce conformément à l'ordre dans lequels ils sont déclarés. AInsi :
Bonne chance
De plus ce constructeur doit explicitement appeler les constructeurs des classes mères (ceci différencie le C++ du java, mais c'est grâce à ce genre de chose qu'on peut faire du multi-héritage en C++).
Exemple :
#include <iostream> template <typename T> class mere_t{ public: mere_t(){ std::cout << "je suis ta mère !" << std::endl; } }; template <typename T> class fille_t : public mere_t<T>{ public: fille_t():mere_t<T>(){ std::cout << "nooooon !" << std::endl; } }; int main(){ fille_t<int> f; return 0; }
Donne :
je suis ta mère ! nooooon !
Je te rappelle aussi que les membres de classes pouvant être initialisés avant l'accolade ouvrante du constructeur doivent l'être, et ce conformément à l'ordre dans lequels ils sont déclarés. AInsi :
class plop_t{ protected: int i; // d'abord i char c; // ensuite c float f; // enfin f public: plop_t(int i0=0,float f0,char c0='x'): i(i0),c(c0),f(f0) // d'abord i, ensuite , enfin f { // code du constructeur (éventuellement vide) } };
Bonne chance
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
3 juin 2008 à 16:34
3 juin 2008 à 16:34
Il me semble que le constructeur par défaut est créé automatiquement si aucun constructeur n'est fourni au compilateur, un peu comme operator= et le destructeur qui sont définis automatiquement.
Par contre, dès que l'on défini un constructeur, le constructeur par défaut (sans argument) doit être défini explicitement si on veux qu'il soit utilisable.
Le problème de Bedevere (je pense) c'est qu'il définit un constructeur par défaut privé et que cela ne crée pas d'erreur lors de la déclaration de la variable. Un constructeur privé empêche la déclaration d'un objet.
Pour s'en convaincre, le code suivant compiler avec gcc 3.2.3 :
Par contre, dès que l'on défini un constructeur, le constructeur par défaut (sans argument) doit être défini explicitement si on veux qu'il soit utilisable.
Le problème de Bedevere (je pense) c'est qu'il définit un constructeur par défaut privé et que cela ne crée pas d'erreur lors de la déclaration de la variable. Un constructeur privé empêche la déclaration d'un objet.
Pour s'en convaincre, le code suivant compiler avec gcc 3.2.3 :
class A{ A(){}; int a; } struct B :public A{ B(){}; //ou B():A(){}; int b; } int main() { A a; // erreur appel direct à un constructeur privé B b; // erreur aussi, B fesant appel au constructeur privé A() return 0; }
mamiemando
Messages postés
33077
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
18 avril 2024
7 748
3 juin 2008 à 20:29
3 juin 2008 à 20:29
Il me semble que le constructeur par défaut est créé automatiquement si aucun constructeur n'est fourni au compilateur
Oui mais non. A priori il faut partir du principe qu'il n'y a pas de constructeur par défaut construit automatiquement (contrairement à = ou au destructeur).
De plus l'appel aux constructeur(s) mère(s) n'est a priori pas fait par défaut (cf message <1>)
Oui mais non. A priori il faut partir du principe qu'il n'y a pas de constructeur par défaut construit automatiquement (contrairement à = ou au destructeur).
(mando@aldur) (~) $ cat plop.cpp class plop_t{ protected: unsigned x; public: plop_t(unsigned x0):x(x0){} }; int main(){ plop_t p = plop_t(); return 0; } (mando@aldur) (~) $ g++ -W -Wall plop.cpp plop.cpp: In function ‘int main()’: plop.cpp:9: error: no matching function for call to ‘plop_t::plop_t()’ plop.cpp:5: note: candidates are: plop_t::plop_t(unsigned int) plop.cpp:1: note: plop_t::plop_t(const plop_t&) plop.cpp:9: warning: unused variable ‘p’ (mando@aldur) (~) $ g++ --version g++ (GCC) 4.2.4 (Debian 4.2.4-1) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
De plus l'appel aux constructeur(s) mère(s) n'est a priori pas fait par défaut (cf message <1>)
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
4 juin 2008 à 08:30
4 juin 2008 à 08:30
C'est bien ce que je disais "si aucun autre constructeur n'est défini", là tu défini plop_t(uint).
Et d'ailleurs, on vois lors de la compilation que ça ne concerne pas le constructeur par copie.
Et d'ailleurs, on vois lors de la compilation que ça ne concerne pas le constructeur par copie.
mamiemando
Messages postés
33077
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
18 avril 2024
7 748
4 juin 2008 à 14:20
4 juin 2008 à 14:20
ok