Bonjour,
On m'assure qu'il est posible de declarer une classe de telle manière qu'elle soit incapable d'avoir une "descendance"?
Il faudrait pour cela utiliser une classe de base virtuelle....
Cela dit quelque chose à quelqu'un?
Merci d'avance
Version imprimable
Bonjour,
On m'assure qu'il est posible de declarer une classe de telle manière qu'elle soit incapable d'avoir une "descendance"?
Il faudrait pour cela utiliser une classe de base virtuelle....
Cela dit quelque chose à quelqu'un?
Merci d'avance
Une classe qui n'aurait pas de constructeur non privé, ou dont le destructeur serait privé ? Par contre, une telle classe ne peut s'utiliser classiquement.
En général, en C++, le simple fait d'avoir un destructeur non virtuel est une documentation indiquant que la classe en question n'est pas conçue pour être dérivée.
Je ne vois pas trop ce qu'une classe de base virtuelle aurait à voir là dedans.
Salut,
de mémoire un classe virtuelle est une classe ayant au moins une fonction virtuelle pure, comme ci dessous :
une telle classe ne peut PAS être instanciée, d'ailleur le constructeur en public n'est pas super utile là...Code:
1
2
3
4
5
6
7
8
9 class A { public: A() { } ~A() { } private: virtual void my_virtual_function() = 0; };
Si elle ne peut être instanciée elle ne peut qu'être détivée... Pour avoir une classe non dérivable il faut trouver autre chose. Je regarde dans mes cours pour retrouver quelque chose qui correcpondrait à ça.
Tarrke
Non, c'est une classe abstraite. Une classe de base virtuelle est autre choseCitation:
un classe virtuelle est une classe ayant au moins une fonction virtuelle pure,
Le terme employé est bien abstraite dans ce cas-la.
Le fait d'utiliser une classe de base virtuelle est soit disant un indice pour resoudre ce probleme...
Mais en fait je dois avouer que j'avais aussi confondu avec une classe abstraite.
Ouuuups
ma faute :oops: !
bon ben je retourne à mes cahiers et je cherche ce que peut être une classe virtuelle alors.
Merci de la reprise, ça m'évitera de la refaire celle là !
Tarrke
Une classe virtuelle ça n'existe pas, le virtuel de "classe de base virtuelle" s'applique à l'héritage. A savoir :
Ca permet d'éviter la duplication des données de Base dans Dérivee, si celle-ci en dérive plusieurs fois (oui ça arrive).Code:
1
2
3
4
5
6
7
8
9 class Base { }; class Derivee : virtual Base { };
Oh oui!! C'est pour les structures dites "en diamant", par exemple, non?
Si ça vous dit quelquechose...
Soit 4 classes C1 C2 C3 C4
Si C2 et C3 herite de C1 et si C4 herite de C2 et C3
Effectivement je ne vois pas en quoi ça concerne mon probleme...
Bonjour,
pour autant que je sache en C++ on ne peut pas interdire la dérivation d'une classe (contrairement à Java).
comme le dit Luc Hermitte, si le destructeur d'une classe n'est pas virtuel, c'est qu'a priori elle n'est pas destiné à être dérivé. cela dit on peut le faire quand même, mais gare au polymorphisme.
Je reviens sur la question initiale.
Oui ton truc est possible, en plus d'être la seule façon "programmée" que je connaisse, mais tordu. On t'avait bien aiguillé.
Je reprends l'idée que j'avais lue dans un post de James (Kanze) sur fclc++. Commentaires dans le code.
L'interdiction est imposée par défaut, mais outrepassable. On paie un vtbl pour l'avoir. Compliqué pour pas grand chose.Code:
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
32
33
34
35
36
37
38 #include <iostream> using namespace std; class CMakeNotInheritable { protected: // private à la place foire tout CMakeNotInheritable() {}; } ; class CTest : private virtual CMakeNotInheritable // virtual nécessaire pour interdire { public: virtual ostream & write(ostream & os) const { return os << "CTest" << endl; } }; class CTest2 : public CTest //, private virtual CMakeNotInheritable // nécessaire pour outrepasser // l'interdiction { public: virtual ostream & write(ostream & os) const { return os << "CTest2" << endl; } void f() { } private: int titi; }; int main (int argc, char **argv) { CTest toto; toto.write(cout); CTest2 tata; tata.write(cout); }
Un commentaire clair et explicite est cencé suffire. Typiquement, il acompagnerait la ligne rappellant la sémantique de la classe, surtout si les objets de cette classe sont censés avoir une sémantique de valeur.
Jolie bidouille :D
Mais pourquoi est-ce que ça produit l'effet attendu ? Mon compilo me dit que CTest2 ne peut pas accéder au constructeur de CMakeNotInheritable, mais je ne vois pas le rapport entre l'héritage virtuel et le fait qu'il le réclame.
8O Moi aussi je veux bien plusde commentaire car je dois dire que je suis pas tres "avancé" en C++ (je connais le langage mais l'utilise peu...)
et donc je suis un peu perdu :oops:
Voici un extrait de la norme qui est nécessaire à la compréhension :
En clair, dans le cas d'une classes de base virtuelles se pose la question de quel constructeur pour cette classe appeler.Citation:
Envoyé par La norme §12.6.2.6
Si on a V, dont hérite virtuellement A et B, et C héritant de A et B, A et B peuvent tous deux spécifier un constructeur différent pour leur classe de base V, or comme il n'existe qu'un seul objet V créer, il faut faire un choix.
Le choix a été fait de ne prendre ni l'appel de A, ni celui de B, mais de demander spécifiquement à l'auteur de C d'expliciter quel constructeur de V doit être appelé.
Ici, comme l'héritage est privé, CTest peut avoir l'accès qu'il veut à l'interface protected de CMakeNotInheritable, mais ne donne à ses descendants que l'accès à sont interface publique. Donc CTest2 a besoin de spécifier le constructeur de CMakeNotInheritable à utiliser, mais n'en au aucun d'accessible, donc boom.
C'est un peu le même principe que dans mon post, pour interdire l'héritage, on empêche par l'utilisation de private la classe dérivée de pouvoir spécifier le constructeur de la classe de base qu'elle veut utiliser, mais l'avantage de cette méthode est qu'elle permet de manipuler cette classe classiquement, alors que la mienne demandait à l'utilisateur de passer par des factories pour créer les objets. D'un autre côté, elle est plus lourde.
Et en tout cas, un commentaire dans le code ou l'absence de destructeur virtuel me semblent les meilleurs solutions.
8O J'ai compris!!! J'ai eu un peu de mal pour tout digerer mais maintenant c'est bon.
Merci