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
Michel Michaud
Dans le message ,
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).


Je ne vois pas comment tu déduis ça : c'est une condition nécessaire
dans l'esprit de C++. Alors oui, je crois qu'on peut se limiter à
2 (qui est égal à 3 non ?). Par contre, la norme, comme je le ferais
moi aussi, ajoute la conséquence et l'aspect le plus important (1).

Je suppose que d'autres langages pourraient bien dire qu'un classe
abstraite est simplement une classe non instanciable, mais ce n'est
pas le cas de C++.

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

Avatar
Vincent Lascaux
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).


Je ne vois pas comment tu déduis ça : c'est une condition nécessaire
dans l'esprit de C++. Alors oui, je crois qu'on peut se limiter à
2 (qui est égal à 3 non ?)


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).

--
Vincent


Avatar
Michel Michaud
Dans le message 41700ec4$0$29560$,
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).


Je ne vois pas comment tu déduis ça : c'est une condition
nécessaire dans l'esprit de C++. Alors oui, je crois qu'on peut se
limiter à
2 (qui est égal à 3 non ?)


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++.

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



Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

| Dans le message ,
| > 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).
|
| Je ne vois pas comment tu déduis ça : c'est une condition nécessaire
| dans l'esprit de C++. Alors oui, je crois qu'on peut se limiter à
| 2 (qui est égal à 3 non ?). Par contre, la norme, comme je le ferais
| moi aussi, ajoute la conséquence et l'aspect le plus important (1).

Personnellement, en cas de doute, je retourne aux sources.

(2).

-- Gaby
Avatar
Luc Hermitte
"Michel Michaud" wrote in news:4MTbd.54081$3C6.2075141
@news20.bellglobal.com:

[...classes abtraites...]

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).


Je ne vois pas comment tu déduis ça : c'est une condition nécessaire
dans l'esprit de C++. Alors oui, je crois qu'on peut se limiter à
2 (qui est égal à 3 non ?)


Abolument pas "A => B" n'est pas equivalent à "B => A". Juste à "non B =>
non A".

(2) dit "Si il y a une fmvp (A) alors (=>) c'est une classe Abstraite
(B)"

(3) dit "A <= B". (ou "B => A"...). Avec l'équivalence complète fortement
sous entendue.

Pour passer de 2 à 3, il manque la condition nécessaire (B => A) qu'il
semblait l'on ait car c'est un détail en C++ : il n'y a pas d'autre façon
absolue (instanciation dans la classe dérivée, ou locale maintenant que
j'y pense) de faire.


L'équivalence est très certainement dans l'esprit du C++, mais alors
pourquoi ne pas de le dire de façon sans équivoque dans la norme ?
Pourquoi cette subtilité dans la formulation ?

C'est juste mal dit, ou j'ai manqué un truc ?

Je suppose que d'autres langages pourraient bien dire qu'un classe
abstraite est simplement une classe non instanciable, mais ce n'est
pas le cas de C++.


D'ailleurs l'exemple de Vincent me fait penser qu'une classe avec les
constructeurs privés, mais qui dispose de fonctions membre statiques
publiques est non instanciable, mais pas dans l'esprit (OO) des classes
abstraites.


--
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
James Kanze
Luc Hermitte writes:

|> 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".

C'est une définition générale qui peut être utile. Ce n'est pas la
définition selon le langage.

|> 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)".

Dans la norme, (1) est une conséquence de (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...

Mais qui n'est pas une classe abstraite au sens de la norme.

|> ... à 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) ?

Tu m'as un peu perdu, mais en ce qui concerne le C++, une classe est
abstraite si et seulement si elle a une ou plus de fonctions membre
virtuelles pûres. C'est la définition.

Le fait qu'on ne peut pas en avoir une instance en est une conséquence.
Mais pas forcement la seule. (Noter, en revanche, que même si on ne peut
pas en créer des instances, il existe bel et bien des objets dont le
type dynamique est celui d'une classe abstraite.)

Maintenant, quand je me place au niveau de la conception, je ne me tiens
pas forcement compte de la définition au niveau du langage. Au niveau de
la conception, une classe abstraite est une classe qui ne DOIT servir
que comme classe de base. Que le compilateur le considère aussi une
classe abstraite, et réfuse de l'instantier, tant mieux, mais
l'importance, c'est son rôle dans la conception, et non ce que le
compilateur en pense. (Et en fait, il m'est arrivé une ou deux fois,
pour de diverses raisons, d'avoir des classes conceptuellement
abstraites sans fonctions virtuelles pûres.)

|> 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.

Tout dépend du niveau où tu te places. La norme C++ ne peut parler que
des formalismes du langage. Si tu implémentes un compilateur C++, c'est
aussi ce qui t'intéresse. Et jusqu'un certain point, aussi quand tu
codes -- tu es au moins intéressé par les possibilités techniques du
langage par rapport aux exigences de ta conception. Mais au niveau de la
conception, évidemment, c'est toute autre chose.

--
James Kanze
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
drkm
James Kanze writes:

(Noter, en revanche, que même si on ne peut
pas en créer des instances, il existe bel et bien des objets dont le
type dynamique est celui d'une classe abstraite.)


Autres que les sous-objets des objets concrets ? J'ai du mal à voir
dans quel cas. Peux-tu donner un exemple ?

--drkm

Avatar
Michel Michaud
Dans le message ,
"Michel Michaud" wrote in
news:4MTbd.54081$3C6.2075141 @news20.bellglobal.com:

[...classes abtraites...]

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).


Je ne vois pas comment tu déduis ça : c'est une condition
nécessaire dans l'esprit de C++. Alors oui, je crois qu'on peut se
limiter à 2 (qui est égal à 3 non ?)


Abolument pas "A => B" n'est pas equivalent à "B => A". Juste à
"non B => non A".


Le texte est peut-être un peu tordu dans sa description, je comprends
ton point de vue. La deuxième phrase dit clairement qu'une classe est
abstraite si elle contient au moins un fonction virtuelle pure. Ce
n'est pas une condition suffisante, c'est une condition nécessaire.
On ne peut pas sortir de là. Il faut donc prendre l'autre phrase comme
disant simplement ce qu'on peut faire d'une classe abstraite avant de
dire ce que c'est (comme le paragraphe qui précède d'ailleurs).
J'avoue que les mettre dans cet ordre ne semble pas idéal pour une
norme, mais c'est dans l'esprit C++ :-)

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



Avatar
Vincent Lascaux
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).


Je ne vois pas comment tu déduis ça : c'est une condition
nécessaire dans l'esprit de C++. Alors oui, je crois qu'on peut se
limiter à
2 (qui est égal à 3 non ?)


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]".

--
Vincent




Avatar
James Kanze
drkm writes:

|> James Kanze writes:

|> > (Noter, en revanche, que même si on ne peut
|> > pas en créer des instances, il existe bel et bien des objets dont le
|> > type dynamique est celui d'une classe abstraite.)

|> Autres que les sous-objets des objets concrets ? J'ai du mal à
|> voir dans quel cas. Peux-tu donner un exemple ?

Dans les constructeurs et les destructeurs. Le type dynamique de l'objet
est bel et bien le type du constructeur ou du destructeur qui s'exécute,
même si ce type est une classe abstraite.

--
James Kanze
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
1 2 3 4 5