Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Terminologie: classe abstraite

53 réponses
Avatar
Luc Hermitte
Salut.

Je me posais une question au sujet de ce qu'était reconnu comme une
classe abstraite.

Jusqu'à présent, ma définition a toujours été : "une classe non
instanciable".

Dans la norme, la formulation ressemble à peu près à : "Une classe
abstraite est non instanciable (1). Une classe est abstraite si elle
dispose d'au moins une fonction membre qui soit virtuelle pure (fmqsvp)
(2)".

Là arrive le pinaillage. J'ai croisé des définitions qui disaient qu'une
"classe abstraite est une classe qui a au moins une fmqsvp" (3).
Si on s'en tient à la formulation officielle, la seconde partie est une
condition suffisante mais non nécessaire. Ce qui ne suffit pas à déduire
(3).

Si on définit une classe dont les constructeurs sont tous au moins
protégés (et dépourvue de créateurs amis ou assimilés, voir les fonctions
statiques des singletons), on arrive aussi à définir une classe qui ne
soit pas instanciable...
... à un détail près: elle peut quand même être instanciée dans les
fonctions membres des descendants de la classe.

struct Abs {
protected:
Abs() {}
};

struct fils : Abs {
void f() { Abs a; }
};


Est-ce ce détail qui nous donne la condition nécessaire (je ne vois pas
d'autres façon d'avoir des classes non instanciables et utilisables (tout
privé)) qui manquait pour justifier la formulation (3) ?

Personnellement, je n'aime pas cette formulation (3) car elle tient du
détail d'implémentation. C'est peut-être bien la seule façon de définir
des classes abstraites en C++, mais ce n'est pas ça qui est réellement
important AHMA.

Bref, j'aurais aimé avoir l'avis d'autres pinailleurs sur la question. Et
eventuellement savoir si j'avais manqué un point.


--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>

10 réponses

1 2 3 4 5
Avatar
Luc Hermitte
James Kanze wrote in
news::

Elle dit « si », et non « si et seulement si ». En plus, c'est dans la
phrase précédante où « abstract class » est écrit en italiques (ce qui
signifie dans la norme qu'il s'agit d'une définition).


Dans mes souvenirs, on n'utilise l'italique qu'une seule fois.

Ça ne correspond pas à ce que j'ai toujours cru, ni ce qu'on m'a
toujours dit.

En revanche, dans la « définition », la norme n'en parle que des
restrictions d'utilisation. Ce qui n'est pas vraiment ce qu'on
s'attend d'une définition dans une norme. Il ne faut pas pousser trop
pour croire que la « définition » comprend en fait les deux phrases,
et que le « si » signifie en fait « si et seulement si ».


Que veux-tu dire ? Qu'il faut comprendre que le "si" est un "ssi", et que
la définition est cuopée en deux ? Ou bien que la norme nous le laisse
croire, alors que cela ne fait pas parti de la définition ?



--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>

Avatar
Luc Hermitte
Luc Hermitte wrote in
news::

Je me posais une question au sujet de ce qu'était reconnu comme une
classe abstraite.
[...]
Bref, j'aurais aimé avoir l'avis d'autres pinailleurs sur la question.
Et eventuellement savoir si j'avais manqué un point.


Meci à tous pour vos avis sur la question.

--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>

Avatar
kanze
Luc Hermitte wrote in message
news:...
James Kanze wrote in
news::

Elle dit « si », et non « si et seulement si ». En plus, c'est dans
la phrase précédante où « abstract class » est écrit en italiques
(ce qui signifie dans la norme qu'il s'agit d'une définition).


Dans mes souvenirs, on n'utilise l'italique qu'une seule fois.


Une seule fois pour une expression donnée. Chaque expression ne doit
avoir qu'une seule définition.

Ça ne correspond pas à ce que j'ai toujours cru, ni ce qu'on m'a
toujours dit.

En revanche, dans la « définition », la norme n'en parle que des
restrictions d'utilisation. Ce qui n'est pas vraiment ce qu'on
s'attend d'une définition dans une norme. Il ne faut pas pousser
trop pour croire que la « définition » comprend en fait les deux
phrases, et que le « si » signifie en fait « si et seulement si ».


Que veux-tu dire ? Qu'il faut comprendre que le "si" est un "ssi", et
que la définition est cuopée en deux ? Ou bien que la norme nous le
laisse croire, alors que cela ne fait pas parti de la définition ?


Je veux dire que j'ai un peu du mal à comprendre moi-même. Si l'italique
indique bien la définition, comme il se doit, alors, ça doit être un si
et seulement si, et non seulement un si. Mais dans ce cas précis, je
ressens une tension entre la formalité qui dit que la définition est
signalée par l'utilisation de l'italique, et la façon naturelle de lire
les phrases (qui ferait de la phrase qui suit la définition, et non la
phrase où il y a l'italique).

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Aurélien REGAT-BARREL
class A { A() {} };

Cette classe respecte 1 (elle n'est pas instanciable car son
constructeur est privé). Elle ne respecte pas 2 (elle n'a pas de
methode virtuelle pure).


Et alors ? Elle n'est pas abstraite au sens de C++.


Moi j'ai pas compris ce qu'elle est alors.
Abstraite (selon quel sens ?) ou pas abstraite (un peu quand même non ?) ?

--
Aurélien REGAT-BARREL


Avatar
Michel Michaud
Dans le message 41750520$0$853$,
class A { A() {} };

Cette classe respecte 1 (elle n'est pas instanciable car son
constructeur est privé). Elle ne respecte pas 2 (elle n'a pas de
methode virtuelle pure).


Et alors ? Elle n'est pas abstraite au sens de C++.


Moi j'ai pas compris ce qu'elle est alors.
Abstraite (selon quel sens ?) ou pas abstraite (un peu quand même
non ?) ?


Pas abstraite (au sens de C++), pour ça il faudrait au moins une
fonction virtuelle pure. (je sais, je me répète !).

Elle est quoi alors ? Elle est non l'instanciable et passablement
inutile, c'est tout ce qu'on peut dire :-)

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/



Avatar
kanze
"Michel Michaud" wrote in message
news:<UNjdd.25663$...
Dans le message 41750520$0$853$,
class A { A() {} };

Cette classe respecte 1 (elle n'est pas instanciable car son
constructeur est privé). Elle ne respecte pas 2 (elle n'a pas de
methode virtuelle pure).


Et alors ? Elle n'est pas abstraite au sens de C++.


Moi j'ai pas compris ce qu'elle est alors. Abstraite (selon quel
sens ?) ou pas abstraite (un peu quand même non ?) ?


Pas abstraite (au sens de C++), pour ça il faudrait au moins une
fonction virtuelle pure. (je sais, je me répète !).

Elle est quoi alors ? Elle est non l'instanciable et passablement
inutile, c'est tout ce qu'on peut dire :-)


Elle est, en principe, instanciable. Tout ce qu'on peut dire, c'est
qu'elle n'est pas instanciée par les seules fonctions qui en aurait le
droit de l'instancier -- chose qu'on sait parce qu'on les voit toutes.
Mais il y a une différence entre non instanciable, et non instancié.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34




Avatar
Aurélien REGAT-BARREL
Moi j'ai pas compris ce qu'elle est alors. Abstraite (selon quel
sens ?) ou pas abstraite (un peu quand même non ?) ?


Pas abstraite (au sens de C++), pour ça il faudrait au moins une
fonction virtuelle pure. (je sais, je me répète !).



Mais est-elle abstraite selon un sens quelconque (et lequel) ?
A la question "Peut-on dire qu'une classe avec un constructeur privé est
abstraite" vous répondez quoi ?

Elle est quoi alors ? Elle est non l'instanciable et passablement
inutile, c'est tout ce qu'on peut dire :-)


Elle est, en principe, instanciable. Tout ce qu'on peut dire, c'est
qu'elle n'est pas instanciée par les seules fonctions qui en aurait le
droit de l'instancier -- chose qu'on sait parce qu'on les voit toutes.
Mais il y a une différence entre non instanciable, et non instancié.


Quelle est selon vous la raison principale entre choisir de rendre abstraite
une classe via le sens C++ classique et via un constructeur privé ?

Merci.
--
Aurélien REGAT-BARREL



Avatar
Christophe Lephay
Vincent Lascaux wrote:
class A { A() {} };

Cette classe respecte 1 (elle n'est pas instanciable car son
constructeur est privé). Elle ne respecte pas 2 (elle n'a pas de
methode virtuelle pure).


Et alors ? Elle n'est pas abstraite au sens de C++.


Je n'ai pas dit le contraire. C'etait juste pour dire que 2 n'est pas
une condition nécessaire pour 1. Mais en relisant le tout, je
m'appercois que la phrase originale est ambigue et que tu as du
comprendre qu'elle signifiait "la seconde partie [(2)] est une
condition suffisante mais non nécessaire [pour une classe abstraite]".


La classe A reste instanciable par des friends ou membres statiques. Donc
elle ne respecte pas 1 ;)

Chris



Avatar
Christophe Lephay
Aurélien REGAT-BARREL wrote:
Quelle est selon vous la raison principale entre choisir de rendre
abstraite une classe via le sens C++ classique et via un constructeur
privé ?


Un constructeur privé ne rend pas en soi une classe non-instanciable. Elle
restreint juste l'accès sur qui peut l'instancier (par exemple un membre
statique factory ou une fonction friend).

Constructeur privé et fonction virtuelle pure ne sont pas deux alternatives
à un même problème. Le premier permet de restreindre la création d'un objet
tandis que la seconde permet d'introduire une hiérarchie polymorphe.

Si on souhaite qu'aucun objet ne soit créé du type de la classe, c'est
probablement qu'on souhaite forcer la création d'objets de types dérivés, ce
qui implique généralement que la hiérarchie soit polymorphe et donc
nécessite des fonctions virtuelles ainsi qu'un constructeur accessible pour
les classes de base.

La seule utilisation pratique que je vois des constructeurs privés sont :
* inhiber la création automatique des constructeurs par le compilateur
(auquel cas une simple déclaration private suffit)
* forcer la création des objets à partir d'un membre statique (singleton,
fabrique, etc) ou, eventuellement, d'un friend

Chris

Avatar
drkm
"Christophe Lephay" writes:

Vincent Lascaux wrote:

class A { A() {} };




La classe A reste instanciable par des friends


Elle n'en a pas.

ou membres statiques.


Elle n'en a pas.

Donc
elle ne respecte pas 1 ;)


Il y a peut-être une petite confusion entre « instanciable » et
« instanciée ». Pour moi, une classe n'est pas instanciable, par
nature, lorsqu'elle est abstraite. Et n'est jamais instanciée, par
construction, dans l'exemple ci-dessus.

Ajouter un friend dans la définition de A ci-dessus permetterait de
l'instancier. Mais cela ne changerait rien s'il s'agissait d'une
classe abstraite.

--drkm




1 2 3 4 5