Salut les devs,
J'ai une question concernant l'héritage en C++.
Est-il possible d'"hériter" des constructeurs de la classe A dont hérite une certaine classe B?
Je m'explique...
Soit une classe A avec 5 constructeurs par paramètres.
Je voudrais que la classe B puisse avoir ces mêmes 5 constructeurs par paramètres sans avoir à ré-emballer/ré-implémenter ces 5 constructeurs.
(Note : marche aussi avec X constructeurs, X> >1 ;) )
Existe-t-il un moyen simple qui permette de faire cela automagiquement (en C++ standard, parce que je crois avoir vu un truc avec boost (InPlaceFactory?) qui permett(r)ait de le faire) ?
Suggestions, idées ou autres sont les bienvenues.
# Ben oui, c'est le principe de la prog objet quand même ...
Posté par Florent C. . Évalué à 1.
[^] # Re: Ben oui, c'est le principe de la prog objet quand même ...
Posté par Sebastien . Évalué à 1.
Désolé si j'ai un peu trop simplifié... :/
Le problème c'est que j'utilise des std::vector<T*>
aggrégés dans un DataVector (pour gérer certains aspects
de persistance des données).
Et pour ces mêmes aspects de persistance de données, il est d'usage
de définir pour chaque classe Bidule, une classe BiduleContainer
qui hérite de DataVector.
Les éléments de DataVector sont alloués dynamiquement, et c'est donc DataVector qui en a la propriété.
Bon je vais pas me répandre dans les détails techniques (que je ne maitrise pas suffisamment d'ailleurs), mais voilà en gros comment ca se goupille :
template<typename T>
class DataVector
{
private:
OwnershipPolicy m_ownPolicy;
typedef std::vector<T*> PtrVector;
PtrVector m_pCont;
public:
DataVector(OwnershipPolicy ownPolicy = OWN_ELEMENTS);
DataVector( InputIerator first, InputIterator last, OwnershipPolicy = VIEW_ELEMENTS );
DataVector( ... );
/* ...*/
}
et donc ensuite on peut definir des classes,
class BiduleContainer : public DataVector { ... }
et c'est donc à ce moment là que je voudrais pouvoir réutiliser les constructeurs par paramètres du template DataVector (principalement le constructeur qui permet de ne pas effacer les objets contenus car ils sont contenus par un autre conteneur qui lui a les droits de propriété.
Est-ce que c'est plus clair ?
Parce que bien entendu, même si je ne suis pas un programmeur C++ de haut niveau (cf [1]) j'ai quand même quelques bases :P
Mon erreur (ou en tout cas une) c'est que je surchargeais l'operateur de construction par défaut ( ie: (void) sans définir d'Ownership par défaut) de ma class BiduleContainer.
Mais le fait que je ne pas construire de BiduleContainer en utilisant la copie par itérateurs.
Voilà voilà...
[1] : https://linuxfr.org/~linuxfan/14787.html(...)
[^] # Détail qui a son importance :
Posté par Sebastien . Évalué à 1.
tous les constructeurs de DataVector sont définis avec le mot clé explicit...
[^] # Re: Détail qui a son importance :
Posté par Sebastien . Évalué à 1.
http://atlas-sw.cern.ch/cgi-bin/viewcvs-atlas.cgi/offline/Control/D(...)
[^] # Re: Ben oui, c'est le principe de la prog objet quand même ...
Posté par pasBill pasGates . Évalué à 2.
Template ou pas = 0 difference, le resultat final est identique.
Les templates n'influent absolument pas sur le code genere a la fin, ils permettent simplement de ne pas reecrire 10x fois la meme chose.
[^] # Re: Ben oui, c'est le principe de la prog objet quand même ...
Posté par Sebastien . Évalué à 1.
class BiduleContainer : public DataVector
{}
int main(int argc, char* argv[])
{
std::vector<Bidule*> desBidules;
fillBidules(desBidules);
BiduleContainer bidules(desBidules.begin(); desBidules.end());
return 0;
}
J'ai bon ?
Mais alors d'où vient mon erreur de compil' ? (C'est une question de pure réthorique, je vous demande pas non plus de programmer à ma place ;))
[^] # Re: Ben oui, c'est le principe de la prog objet quand même ...
Posté par pasBill pasGates . Évalué à 3.
Maintenant, on va pas pouvoir t'expliquer ton erreur de compil si tu ne dis pas ce qu'est cette erreur de compilation, on n'a pas tous des talents de voyant...
Si ce que tu viens de taper est ce que tu as dans ton code, le gros probleme evident que c'est que :
class BiduleContainer : public DataVector
ne specifie pas le type de DataVector(puisque c'est un template, faut preciser sur quel type il opere)
Genre faudrait faire :
class BiduleContainer : public DataVector< int >
[^] # Re: Ben oui, c'est le principe de la prog objet quand même ...
Posté par Sebastien . Évalué à 1.
J'ai répondu un peu trop vite et un peu trop tôt dans la matinée.
Donc, oui, c'est bien class BiduleContainer : public DataVector
que j'ai dans mon code.
Lorsque j'essaye d'instancier un container de Bidule-s via :
BiduleContainer bidules( selectionDeBidules.begin(), selectionDeBidules.end() );
J'ai çà comme erreur de compilation :
bidulesSelect.cxx:541: no matching function for call to `
BiduleContainer::BiduleContainer(
__gnu_cxx::__normal_iterator<Bidule**, std::vector<Bidule*,
std::allocator<Bidule*> > >,
__gnu_cxx::__normal_iterator<Bidule**, std::vector<Bidule*,
std::allocator<Bidule*> > >)'
BiduleContainer.h:21: candidates
are: BiduleContainer::BiduleContainer()
bidulesSelect.cxx:239:
BiduleContainer::BiduleContainer(const BiduleContainer&)
Donc si je comprends bien ce que me dit gcc3.2, il ne voit que les constructeurs par défaut et par copie, automatiquement générés par le compilo. Et pas ceux de la classe de base (DataVector).
En tout cas merci de tes réponses.
[^] # Re: Ben oui, c'est le principe de la prog objet quand même ...
Posté par LeMagicien Garcimore . Évalué à 2.
Je pense pas, il manques les points virgules à la fin de la déclaration des classes)
Et ça ne marche pas, les constructeurs ne sont pas hérités (cf le message de Roulious). D'ailleurs gcc (3.2.3) me lance un warning :
base `A' with only non-default constructor in class without a constructor
D'ailleurs d'aprés mes souvenir de prog objet, le fait que les constructeurs ne soient pas hérités est logique. A et B sont deux types différents, on ne peut donc pas les instancier de la même façon. En y réfléchissant, les rares langages de POO que je connais ne le font pas.
En c++, si je ne me trompe pas, les seuls constructeurs implicites sont le contructeur par defaut et le constructeur par copie. Il ne sont ajoutés que si l'utilisateur ne défini pas lui même des contructeurs.
Un cpp-guru pour clarifier ?
[^] # Re: Ben oui, c'est le principe de la prog objet quand même ...
Posté par Roulious . Évalué à 1.
C'est presque ça : un constructeur par défaut est ajouté uniquement s'il n'y a aucun autre constructeur défini, que ce soit un constructeur de copie ou un autre constructeur. Pour le constructeur de copie, il est effectivement ajouté lorsque l'utilisateur n'en définit pas un lui même.
# Les constructeurs ne sont pas des fonctions membre
Posté par Roulious . Évalué à 1.
Je n'ai rien vu dans la Boost qui permettrait de faire ça, mais je n'ai pas trop cherché.
Est-tu sur que tu as absolument besoin d'un héritage ?
[^] # Re: Les constructeurs ne sont pas des fonctions membre
Posté par Sebastien . Évalué à 1.
http://www.boost.org/libs/optional/doc/optional.html#inplace(...)
Bon ensuite, au niveau de l'heritage...
L'heritage n'est pas a priori necessaire (un typedef pourrait suffir) pour l'utilisation en elle-meme de la classe.
Cependant, il me faut surcharger des fonctions necessaires lors de la relecture (des objets instanties) a partir de fichiers sur disque (RTTI toussa quoi, du genre identification du type d'objet stocke (son nom, son espace de serialisation,... ) ).
Donc bon.
Apparemment pas de solution miracle. C'est vraiment trop injuste :P
Mais merci de ta reponse.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.