[C++] Extra constructors van base class in derived class?

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik heb een base class met een extra constructor (zeg Cbase::Cbase(int)).
Nu heb ik ook een groot aantal derived classes, waar ik deze constructor ook wil gebruiken.
Moet ik nu in al die derived classes handmatig die constructor toevoegen of is er een manier om de constructor van de base class te gebruiken?

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

C++:
1
2
3
4
5
6
7
8
9
10
class Base {
public:
   Base(int i) {...}
};

class Derived : public Base {
public:
   Derived() : Base(0) {...}
   Derived(int i) : Base(i) {...}
};

Zoiets?

[ Voor 4% gewijzigd door Zoijar op 17-10-2004 20:21 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ja, maar dan dus zonder expliciet in derived die constructors te hoeven zetten.

[ Voor 7% gewijzigd door Olaf van der Spek op 17-10-2004 20:26 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Hoe moet de compiler dan weten hoe je Base wilt constructen? Je wilt Base(int) gebruiken, maar met welke int dan? Anders kan je een default zetten misschien? Base(int i=0) oid. Of een extra default ctor in Base?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Nog niet, maar dit wordt in C++0x misschien wel mogelijk. Het voorstel is
C++:
1
2
3
4
5
6
7
8
//C++0x
class Base {
  Base() {};
  Base(int) {};
};
class Der {
  default Der(int); // DWIW
};

[ Voor 3% gewijzigd door MSalters op 18-10-2004 17:37 . Reden: close tag ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Zoijar schreef op 17 oktober 2004 @ 21:44:
Hoe moet de compiler dan weten hoe je Base wilt constructen? Je wilt Base(int) gebruiken, maar met welke int dan?
Op dezelfde manier als een normale functie die alleen in Base defined is.

Verwijderd

OlafvdSpek schreef op 18 oktober 2004 @ 17:46:
Op dezelfde manier als een normale functie die alleen in Base defined is.
En hoe weet de compiler dan welke waarden je voor de parameters van die functie wil als die parameters geen default waarden nemen? :?

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 18 oktober 2004 @ 20:24:
En hoe weet de compiler dan welke waarden je voor de parameters van die functie wil als die parameters geen default waarden nemen? :?
Die parameter geef je toch gewoon mee?

Je gebruikt bijvoorbeeld new Derived(5) en de compiler geeft die 5 dan automatisch door aan Base(int).

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
MSalters schreef op 18 oktober 2004 @ 17:37:
Nog niet, maar dit wordt in C++0x misschien wel mogelijk. Het voorstel is
Waar staat DWIW voor?
En dat betekent dat ik alsnog 100 keer die derived class aan moet passen.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:59

.oisyn

Moderator Devschuur®

Demotivational Speaker

Meestal init je de members toch al in de constructor, een expliciete aanroep naar de base classes kan daar ook nog wel bij imho

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Het scheelt wel werk. Toch vraag ik me af hoe netjes het is. Immers de functionaliteit van de base class kan nu veranderen door middel van die integer. Deze stap slaat de derived classes geheel over, als ik het goed begrijp.

De ontwerper van een derived class kan er dus niet echt meer op aan dat de implementatie, of belangrijker de functionaliteit, van de baseclass waarop hij zijn ontwerp heeft gebaseerd hetzelfde blijft. Bij het expliciet toevoegen van een constructor geeft dit een extra controle-laag die de derived class de mogelijkheid geeft om hierop in te spelen.

Aan de andere kant geeft het wel meer flexibele mogelijkheden om in latere stages in het ontwikkelproces, of na oplevering, nog wijzigingen door te voeren.

Nou goed, ik zet m'n vraagtekens erbij, maar de mensen van de C++ standaard zullen ongetwijfeld goede redenen hebben om dit (eventueel) op te nemen in de komende standaard ;)

[Edit]Oh ik zie nu dat de derived class bepaalt of er gebruik mag worden gemaakt van de default 'routing' naar de base class constructor. Wat is dan het verschil met een expliciete constructor maken of deze nieuwe construct? Behalve dat het 'korter' is?

[ Voor 13% gewijzigd door Orphix op 18-10-2004 22:01 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
.oisyn schreef op 18 oktober 2004 @ 21:41:
Meestal init je de members toch al in de constructor, een expliciete aanroep naar de base classes kan daar ook nog wel bij imho
In dit geval hebben de vele derived classes geen constructors en geen members.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Orphix schreef op 18 oktober 2004 @ 21:57:
Het scheelt wel werk. Toch vraag ik me af hoe netjes het is. Immers de functionaliteit van de base class kan nu veranderen door middel van die integer. Deze stap slaat de derived classes geheel over, als ik het goed begrijp.
Nee, de constructor van de base class wordt nog steeds aangeroepen met dezelfde integer.
Het is alsof gewoon alsof er impliciet de volgende code staat in de derived class:
C++:
1
Derived(int i): Base(i) {} 

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:59

.oisyn

Moderator Devschuur®

Demotivational Speaker

MSalters schreef op 18 oktober 2004 @ 17:37:
Nog niet, maar dit wordt in C++0x misschien wel mogelijk. Het voorstel is
[..knip..]
Is er trouwens iets van een internetpagina waar al die voorstellen en/of discussies te bekijken zijn?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Dim
  • Registratie: Januari 2000
  • Laatst online: 09-05 19:58

Dim

.oisyn schreef op 18 oktober 2004 @ 22:11:
[...]
Is er trouwens iets van een internetpagina waar al die voorstellen en/of discussies te bekijken zijn?
http://www.research.att.c...q.html#When-next-standard
http://www.research.att.com/~bs/evol-issues.html

en bij Herb Sutter is ook nog wel iets te vinden:

http://www.gotw.ca/publications/index.htm

Helaas lijkt er niet een pagina te zijn waar al dit spul samengevat wordt, misschien tijd om eens een FAQ te maken. ;)

My other computer is your windows box.


Verwijderd

OlafvdSpek schreef op 18 oktober 2004 @ 21:25:
Die parameter geef je toch gewoon mee?

Je gebruikt bijvoorbeeld new Derived(5) en de compiler geeft die 5 dan automatisch door aan Base(int).
Juist, daar heb je volledig gelijk. Maar Zoijar stelde de vraag voor het geval je natuurlijk de Derived() constructor gebruikt uit de Derived interface. Hoe moet je compiler dan de juiste waarde uitvissen? Niet denk ik, dus in dat geval kan de compiler niet alle werk voor jou doen. Akkoord? :)

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 18 oktober 2004 @ 23:48:
Juist, daar heb je volledig gelijk. Maar Zoijar stelde de vraag voor het geval je natuurlijk de Derived() constructor gebruikt uit de Derived interface. Hoe moet je compiler dan de juiste waarde uitvissen? Niet denk ik, dus in dat geval kan de compiler niet alle werk voor jou doen. Akkoord? :)
Oh, op die manier.
Dat mag de compiler natuurlijk niet toestaan. Maar in mijn situatie heb ik ook een standaard (parameterloze) constructor in Base.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
.oisyn schreef op 18 oktober 2004 @ 22:11:
[...]
Is er trouwens iets van een internetpagina waar al die voorstellen en/of discussies te bekijken zijn?
http://www.open-std.org/j...cs/papers/2004/n1700.html

Alhoewel er zojuist al twee items daarvan gesneuveld zijn; de commissie zit nu in meeting.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
OlafvdSpek schreef op 18 oktober 2004 @ 21:26:
[...]

Waar staat DWIW voor?
En dat betekent dat ik alsnog 100 keer die derived class aan moet passen.
DWIW = Do What I Wanted
En ja, je moet het 100x aanpassen. Dat is opzet. Constructors zijn bijzonder genoeg dat je ze niet zomaar in derived classes wil introduceren, bijvoorbeeld omdat ze impliciete conversies introduceren. Een int->Derived conversie moet een expliciete keus zijn.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
MSalters schreef op 19 oktober 2004 @ 01:07:
DWIW = Do What I Wanted
En ja, je moet het 100x aanpassen. Dat is opzet. Constructors zijn bijzonder genoeg dat je ze niet zomaar in derived classes wil introduceren, bijvoorbeeld omdat ze impliciete conversies introduceren. Een int->Derived conversie moet een expliciete keus zijn.
Dan zouden ze toch met 'explicit' geintroduceerd kunnen worden?

Verwijderd

OlafvdSpek schreef op 18 oktober 2004 @ 22:02:
[...]

In dit geval hebben de vele derived classes geen constructors en geen members.
Wat zou je dan in de constructor willen initialiseren ? Ik ben benieuwd wat je bouwd. Gokje: combo flyweight/strategy !

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
OlafvdSpek schreef op 19 oktober 2004 @ 10:07:
[...]

Dan zouden ze toch met 'explicit' geintroduceerd kunnen worden?
Nee, zelfs met explicit kun je nog onbedoelde effecten krijgen. Het probleem is dan kleiner, en wordt hetzelfde probleem als wat je hebt met 2+ arg-ctors: Elke class heeft ctors, al dan niet default.

Een functie foo(Y) in een derived class zorgt ervoor dat de base members foo(X) niet meer zichtbaar zijn. Dat is nodig, zodat gegeven class X, Y met impliciete conversie X(Y const&), en derived::foo(X) de call myDer->foo( Y() ) niet verandert als de functie base::foo(Y) wordt toegevoegd.

Voor foo is de oplossing using Base::foo, maar voor ctors is dat niet precies de bedoeling. Je wil namelijk wel een Derived ctor gebruiken, alleen is dat een Derived ctor die vervolgens de bijbehorende Base ctor aanroept.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 19 oktober 2004 @ 13:07:
Wat zou je dan in de constructor willen initialiseren ? Ik ben benieuwd wat je bouwd. Gokje: combo flyweight/strategy !
Wat is flyweight?
En in de base constructor doe ik natuurlijk wel wat.

Verwijderd

OlafvdSpek schreef op 19 oktober 2004 @ 18:11:
[...]

Wat is flyweight?
En in de base constructor doe ik natuurlijk wel wat.
Flyweight is een patroon waarbij er een klasse is waarvan de interne toestand los staat van de omgeving. De lol hiervan is dat deze objecten maar 1x aangemaakt hoeven te worden om vervolgens op allerlei manieren gebruikt te worden.

Bv bij een brief die uit letters bestaat. Voor alle letters houdt het document referenties bij naar maar een beperkte hoeveelheid letter-objecten. Is het document is maar 1 text-stijl, dan zijn er dus maar iets van 60 letter-objecten, hoe lang het document ook zijn mag. De inhoud van het document bestaat eigenlijk alleen maar uit een collectie pointers. Bij weergeven van het document loopt het document de referenties in het zichtbare gedeelte na om zich te tekenen.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Nee, ik heb een base class Ccc_file en allerlei derived classes voor verschillende formats/types (AVI/WAV/etc).
Nu wilde ik een constructor toevoegen aan Ccc_file die een blok memory als parameter heeft en dat bestand dan zeg maar 'laad', zodat ik dat kon gebruiken in alle derived classes. Maar dat ging dus niet.

Verwijderd

OlafvdSpek schreef op 19 oktober 2004 @ 21:15:
Nee, ik heb een base class Ccc_file en allerlei derived classes voor verschillende formats/types (AVI/WAV/etc).
Nu wilde ik een constructor toevoegen aan Ccc_file die een blok memory als parameter heeft en dat bestand dan zeg maar 'laad', zodat ik dat kon gebruiken in alle derived classes. Maar dat ging dus niet.
Waarom bouw je geen abstracte base class met abstracte methoden als laad() en speel() ? Als ik de base constructor al een parameter zou geven, zou het een bestandsnaam worden.

Kijk ook eens naar het patroon "proxy". Misschien is het handig om niet altijd de hele file in geheugen te hebben.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 19 oktober 2004 @ 23:24:
Waarom bouw je geen abstracte base class met abstracte methoden als laad() en speel() ? Als ik de base constructor al een parameter zou geven, zou het een bestandsnaam worden.

Kijk ook eens naar het patroon "proxy". Misschien is het handig om niet altijd de hele file in geheugen te hebben.
Ik gebruik memory mapping, dus zo erg is het niet. Verder zijn het zeer vaak relatief kleine bestanden.
Als ik een base constructor gebruik, dan kom ik toch nooit meer in een derived class?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Het patroon wat je nodig hebt is Factory. Factory.create( ) is de functie die je byte array accepteert, en een smart_ptr<Ccc_file> teruggeeft.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Maar hoe 'upcast' ik die pointer naar de juiste derived class dan (een class met WAV functies voor een WAV file bijvoorbeeld)?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
In theorie, niet. Je play functies e.d. zijn virtual in de (abstract) base. In de praktijk kun je soms een dynamic_cast< > gebruiken.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Oh, op die manier. Maar de base class is een class voor binaire files, niet speciaal voor audio, image of video files.
Het is toch niet de bedoeling al die methods al in de base class te voegen?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17-05 17:19
OlafvdSpek schreef op 20 oktober 2004 @ 18:02:
Oh, op die manier. Maar de base class is een class voor binaire files, niet speciaal voor audio, image of video files.
Het is toch niet de bedoeling al die methods al in de base class te voegen?
Als je een factory gebruikt, kan die de omzetting doen van BinFile->AudioFile. De rest van je app ziet dan die hele BinFile interface niet, alleen de AudioFile interface.

De vraag is dus eigenlijk hier of subclassing BinFile -> AudioFile wel correct/handig is.

Anywayz, als je de rest van je prog alleen de AudioFile interface laat gebruiken is er niets aan de hand. Je hoeft je BinFile interface dan geen play methoden etc te geven.

( Schiet me ook iets te binnen over multiple inheritance, als je dat zou willen )

[ Voor 7% gewijzigd door farlane op 20-10-2004 19:03 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1