OVH Cloud OVH Cloud

[Newbie] Constructeur et héritage

19 réponses
Avatar
TSalm
Bonjour,

J'hérite de la classe std::string, mais je ne spécifie pas de
constructeurs dans ma classe fille.

Mon compilateur refuse alors allégrement un
ExtString("bla bla bla");
En me répondant que le constructeur n'existe pas...
Est-elle impossible d'hériter implicitement des constructeurs des
classes parentes ?
Dois-je vraiment respécifier tout les constructeurs ?

d'avance merci pour votre aide,
TSalm

Exemple pour illustrer mon probléme :
//-------------------------CODE---------------------------------
#include <iostream>
#include <string>

using namespace std;

class extString: public string {
public:
// extString(char * c) : string(c) {
// cout << "construct" << endl;
// }

int getSomething() {
return 12;
}
};

int main()
{
extString s("hello");
cout << s.getSomething() << endl;
return 0;
}
//------------------------FIN CODE----------------------------

9 réponses

1 2
Avatar
Loïc Joly
Le Thu, 07 Jun 2007 23:41:12 +0200, Fabien LE LEZ
Mais si tu crées une nouvelle classe, c'est parce que ce que fait
std::string ne te convient pas, non ?



Oui et non, j'aurais voulu AJOUTER des fonctionnalitées
supplémentaires.


Par curiosité, quelles fonctionnalités voudrais-tu ajouter ? Ne peux tu
pas le faire avec des fonctions libres ?

--
Loïc


Avatar
TSalm
Le Fri, 08 Jun 2007 00:37:37 +0200, Loïc Joly

Le Thu, 07 Jun 2007 23:41:12 +0200, Fabien LE LEZ
Mais si tu crées une nouvelle classe, c'est parce que ce que fait
std::string ne te convient pas, non ?



Oui et non, j'aurais voulu AJOUTER des fonctionnalitées
supplémentaires.


Par curiosité, quelles fonctionnalités voudrais-tu ajouter ? Ne peux tu
pas le faire avec des fonctions libres ?


Je veux ajouter des méthodes Serialise et DeSerialise qui
respectivement prennent en argument un istream et un ostream.

Mais je me rends compte que ce que je veux faire n'est pas une bonne
idée. Il me semble plus pertinant de surcharger l'opérateur << et >>,
mais le principe d'étendre std::string reste toujours le même.



Avatar
Fabien LE LEZ
On Fri, 08 Jun 2007 00:57:25 +0200, TSalm :

Je veux ajouter des méthodes Serialise et DeSerialise qui
respectivement prennent en argument un istream et un ostream.

Mais je me rends compte que ce que je veux faire n'est pas une bonne
idée.


Exact.

Il me semble plus pertinant de surcharger l'opérateur << et >>,


Pas vraiment.
Mieux vaut écrire une fonction
void Serialise (ostream&, string const&)

Avatar
Loïc Joly

Mais je me rends compte que ce que je veux faire n'est pas une bonne
idée. Il me semble plus pertinant de surcharger l'opérateur << et >>,
mais le principe d'étendre std::string reste toujours le même.


Les opérateurs << et >> pour des streams et des strings existent déjà,
tu ne peux donc pas définir les tiens. Donc, soit tu utilise une
fonction libre à deux arguments (proposition de fabien), soit tu utilise
une classe de flux faite sur mesure pour la sérialisation (c'est la
solution utilisée par exemple par boost::serialization).

--
Loïc

Avatar
Alain Gaillard
Le Thu, 07 Jun 2007 22:35:48 +0200, TSalm a écrit :

Mais je perdrais du même coup toute les méthodes inhérentes à la
classe string


Il te suffit d'invoquer les méthodes de la string membre...


--
Alain

Avatar
TSalm
Le Fri, 08 Jun 2007 09:01:09 +0200, Loïc Joly


Mais je me rends compte que ce que je veux faire n'est pas une bonne
idée. Il me semble plus pertinant de surcharger l'opérateur << et >>,
mais le principe d'étendre std::string reste toujours le même.


Les opérateurs << et >> pour des streams et des strings existent déjà,
tu ne peux donc pas définir les tiens.


oups, évidemment

Bon, je n'arrive décidement pas à comprendre cette réticence à étendre
std::string. Mais effectivement, pour le cas particulier de la
serialisation, il est au bout du compte pas une bonne idée d'ajouter
des méthodes de sérialisation/de-sérialisation.


Donc, soit tu utilise une
fonction libre à deux arguments (proposition de fabien), soit tu utilise
une classe de flux faite sur mesure pour la sérialisation (c'est la
solution utilisée par exemple par boost::serialization).



Décidemment, Boost sait tout faire !
Merci à tous pour votre aide.

TSalm


Avatar
Fabien LE LEZ
On Fri, 08 Jun 2007 23:02:51 +0200, TSalm :

Bon, je n'arrive décidement pas à comprendre cette réticence à étendre
std::string.


Il ne s'agit pas d'"étendre", mais d'hériter.
L'héritage est une relation très forte entre deux classes, et n'est à
utiliser qu'après mûre réflexion.
Par ailleurs, std::string (de même que vector<> et compagnie) sont
explicitement prévues pour ne pas être dérivées.

Enfin, contrairement à ce qui a été fait pour std::string, il est
fortement conseillé d'éviter de rajouter des fonctions membres quand
ce n'est pas indispensable.
Déclarer une fonction comme membre, c'est dire au compilateur "Cette
fonction a accès aux membres privés de la classe". C'est loin d'être
anodin, et ça doit être réservé aux cas où tu as réellement besoin
d'accéder aux membres privés.

Avatar
jeremie fouche
On Fri, 08 Jun 2007 23:02:51 +0200, TSalm :

Il ne s'agit pas d'"étendre", mais d'hériter.
L'héritage est une relation très forte entre deux classes, et n'est à
utiliser qu'après mûre réflexion.
...


Déclarer une fonction comme membre, c'est dire au compilateur "Cette
fonction a accès aux membres privés de la classe".


Heuuu, oui et non. Cela dépend du type d'héritage (private).
Attention, ne me fais pas dire ce que je n'ai pas dis. Je suis tout a
fait d'accord avec vous sur le principe, j'ajoute cela uniquement afin
de ne pas faire de raccourci trop rapide entre héritage et accès aux
membres privés.
--
Jérémie

Avatar
TSalm
Le Thu, 07 Jun 2007 22:25:34 -0000, Vianney Lançon


http://www.gotw.ca/gotw/084.htm



lien très interressant, merci

1 2