[C++] Shared functions: in class of niet?

Pagina: 1
Acties:
  • 106 views sinds 30-01-2008
  • Reageer

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Topicstarter
Situatie:

Ik ben (zoals altijd) bezig met het bouwen van een GUI. Nou heb ik het voor de verandering eens met classes aangepakt (aot met structs en alle functies global). Ik heb een basisklasse -- aw_window (Aurora Window, daar staat aw voor) -- waar alle 'algemene' functies in staan zoals init() (voor een window), destroy() enzovoort enzovoort. Dit heeft als voordeel dat je je class data members niet public hoeft te declareren.

Probleem:
Alles goed en wel, maar ik zit er dus over te denken om de algemene functies globaal te maken, omdat zoals ik het nu heb, elke instantie een bonk code bij zich heeft, terwijl dat in principe niet hoeft. Maar als ik die algemene functies globaal maak (voor de n00b: dwz dat ze niet gedefinieerd staan in de class, maar gewoon in het programma zelf), betekent dat dat ik ofwel (bijna) alle data members public moet maken, ofwel dat ik voor (bijna) alle data members een get/set functie moet coden.

Ik ben niet zo voor dat laatste, aangezien ik zo ben dat ik er dan allemaal controle-code omheen smijt. Bovendien moet ik dan twee keer zoveel functies schrijven als dat er members zijn.

Maar ik ben ook niet voor de eerste mogelijkheid (alle members public maken), omdat mijn GUI een library moet worden, wat dus betekent dat n00b/onvoorzichtige/kwaadwillende coders onheil kunnen aanrichten met NULL-pointer references en nog meer evil stuff.

Dus, ziehier mijn probleem. Let's have some solutions! :P

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Wat was er precies mis met inheritance?

:? * drm begrijpt je verhaal niet zo goed

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • whoami
  • Registratie: December 2000
  • Laatst online: 19:39
Als je het object georienteerd wilt doen, kun je gebruik gaan maken van inheritance [zie bovenstaande reply]. Je maakt een basisklasse 'window' bv, waarin je alle basisfunctionaliteit in implementeert. Daarna kan je verschillende classes gaan afleiden van die basisklasse die alle basisfunctionaliteit dus gewoon overerft en per class implementeer je specifieke eigenschappen.

https://fgheysels.github.io/


Verwijderd

Ik heb een basisklasse -- aw_window (Aurora Window, daar staat aw voor) -- waar alle 'algemene' functies in staan zoals init() (voor een window), destroy() enzovoort enzovoort. Dit heeft als voordeel dat je je class data members niet public hoeft te declareren.
Bedoel je dat je een base class hebt waar alle andere classes van gederived zijn, of een class met daarin een zooi static member functions die je anders global zou maken ?
Dit heeft als voordeel dat je je class data members niet public hoeft te declareren.
Ikke niet snappe :'(
zoals ik het nu heb, elke instantie een bonk code bij zich heeft
Nee, objects hebben geen functie-code in hun physieke object zitten.

Verder krijg ik lichtelijk het gevoel dat jij het keyword "friend" misschien wel interessant zou vinden.

  • Banpei
  • Registratie: Juli 2001
  • Laatst online: 16-09 08:48
Standaard regel van OOP: datamemebers NOOIT public of global maken... Dus helaas moet je dan allerhande get/set functies inbouwen... Je kan ook een aantal bij elkaar pakken in een algemeen set commando...

Voorbeeld:
bool bSetUser (int iUserId, string sUsernaam, string sNick, string sPassword)

Dat scheelt ook namelijk een hoop verschillende sets maken... ;)

  • whoami
  • Registratie: December 2000
  • Laatst online: 19:39
Op maandag 01 oktober 2001 14:53 schreef Sneech het volgende:


Verder krijg ik lichtelijk het gevoel dat jij het keyword "friend" misschien wel interessant zou vinden.
Ik denk niet dat friend functies hier aan de orde zijn.
Datamembers die je nodig hebt in afgeleide classes gewoon protected maken zou toch voldoende moeten zijn.

https://fgheysels.github.io/


Verwijderd

Op maandag 01 oktober 2001 14:56 schreef Banpei het volgende:
Standaard regel van OOP: datamemebers NOOIT public of global maken...
Onzin, je moet alleen eerst goed nadenken over de mogelijke gevolgen van het public maken van een data member. Als het in een class toepasselijk is om een bepaalde data member read/write te maken, moet je dat gewoon doen.

Dit:
code:
1
a.x += 3;

is natuurlijk wel 100 x mooier dan dit:
code:
1
a.set_x (a.get_x() + 3);

Wat mensen vaak verkeerd doen is een data member public maken omdat ie moet kunnen worden uitgelezen, en vervolgens vergeten dat ie zo ook writable is.. |:(

Verwijderd

Op maandag 01 oktober 2001 15:04 schreef whoami het volgende:

[..]

Ik denk niet dat friend functies hier aan de orde zijn.
Datamembers die je nodig hebt in afgeleide classes gewoon protected maken zou toch voldoende moeten zijn.
Hij had het erover dat ie functies had die geen toegang hadden tot de private stuff van een class. Daar zijn friend function directives voor.

  • Haywire
  • Registratie: Januari 2000
  • Laatst online: 06-12-2025

Haywire

 

Als ik het goed begrijp ben je bang dat je code voor elke instantie die je aanmaakt in het geheugen terecht komt, dus dat elk object zijn eigen stukje code heeft. Dit is een mooie manier om erover te denken op ontwikkel-niveau (dat is een belangrijk idee van OO programmeren), maar technisch is het heel anders geimplementeerd.

Member-code van een C++-klasse zal nooit meerdere keren voorkomen voor meerdere instanties van dezelfde klasse (tenminste, zeg nooit nooit, misschien ben ik me niet bewust van een uitzondering, maar neem dat voor het gemak maar even aan). De instanties bestaan in werkelijkheid alleen uit data. Member-functies zijn "onder water" gewone functies die als argument een pointer naar je object/instantie meekrijgen.

Als je code uit "verwante" klasses copieert, omdat ze dezelfde functionaliteit nodig hebben, krijg je wel het effect dat je code "dubbel" in het geheugen voorkomt. Hiervoor is echter overerving (inheritance) bedacht. De gemeenschappelijke functionaliteit stop je in een basis-klasse, en specifieke functionaliteit stop je in afgeleide klassen. Op die manier zal slechts 1 keer de code van de basisklasse in het geheugen staan, hoe veel verschillende objecten je ook aanmaakt van verschillende afgeleide klassen van je basisklasse.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Sneech: is natuurlijk wel 100 x mooier dan dit
Jij zult de properties van C# wel mooi vinden :)

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • whoami
  • Registratie: December 2000
  • Laatst online: 19:39
Op maandag 01 oktober 2001 15:07 schreef Sneech het volgende:

[..]

Hij had het erover dat ie functies had die geen toegang hadden tot de private stuff van een class. Daar zijn friend function directives voor.
Wel, misschien kan hij er eens over nadenken om die stuff protected te maken ipv private. Dit zou een mooiere oplossing zijn dan het gebruiken van friend functies. Eigenlijk zijn friend functies een beetje tegen de regels van OO.

https://fgheysels.github.io/


Verwijderd

Op maandag 01 oktober 2001 15:10 schreef mbravenboer het volgende:

[..]

Jij zult de properties van C# wel mooi vinden :)
Je gaat me niet vertellen dat je die 2e versie eleganter vindt...

Verder ga ik voorlopig niet C# leren, aangezien ik eerst meer Java wil leren (wat ik overigens alleen doe omdat Java zo populair is, het concept van .net spreekt me meer aan).

  • whoami
  • Registratie: December 2000
  • Laatst online: 19:39
Op maandag 01 oktober 2001 15:13 schreef Sneech het volgende:

[..]

Je gaat me niet vertellen dat je die 2e versie eleganter vindt...

Verder ga ik voorlopig niet C# leren, aangezien ik eerst meer Java wil leren.
Volgens mij doelt mbravenboer op iets anders.

Adhv properties kun je private datamembers ook 'setten' en 'getten' zonder expliciet gebruik te maken van get en set functies.

https://fgheysels.github.io/


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Sneech: Je gaat me niet vertellen dat je die 2e versie eleganter vindt...
In dit geval niet echt nee, maar het komt eigenlijk maar zelden voor dat je: setX(getX() ... ) gebruikt. Meestal is het iets in de vorm van getX(); ... ; setX(...). In dat geval vind het ik de get/set oplossing geen probleem.
het concept van .net spreekt me meer aan.
Het is errug off-topic, maar wat spreekt je dan meer aan bij .NET?

C# is trouwens vrijwel identiek aan Java, dus wat dat betreft hoe je er zowat maar 1 te leren :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Op maandag 01 oktober 2001 15:11 schreef whoami het volgende:
Eigenlijk zijn friend functies een beetje tegen de regels van OO.
En daarom is C++ een multi-paradigm taal ;)

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
whoami: Volgens mij doelt mbravenboer op iets anders.
Ik had inderdaad niet echt kritiek op de eerste oplossing, maar als je voor die oplossing properties kan gebruiken is dat een aardige oplossing.
Adhv properties kun je private datamembers ook 'setten' en 'getten' zonder expliciet gebruik te maken van get en set functies.
Inderdaad, die worden gegeneerd :) . Syntaxtische suiker dus.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • whoami
  • Registratie: December 2000
  • Laatst online: 19:39
Op maandag 01 oktober 2001 15:16 schreef Sneech het volgende:

[..]

En daarom is C++ een multi-paradigm taal ;)
idd, maar dat mag geen aanmoediging zijn om friend functies te gaan gebruiken.

https://fgheysels.github.io/


Verwijderd

[errug offtopic (op verzoek van mbravenboer)]

Wat me aanspreekt van .net..

Meerdere talen die in het framework saampjes fijntjes draaien volgens open standaarden.

Ik krijg het gevoel dat Microsoft minder misbruik gaat maken van hun machtspositie binnen het .NET platform, dan Sun binnen het Java platform.

En als ik kijk naar die 2 open letters die laatst door Sun en Microsoft gestuurd zijn, komt Microsoft daar ook wel een stuk beter uit.

Overigens weet ik nog niks zeker hoor, Java bewijst zich al als een stabiel en vruchtbaar platform, .NET moeten we nog maar afwachten. En het feit dat ik bezig ben met Java leren (hoewel dat vrij langzaam gaat met zo weinig vrije tijd :() geeft ook aan dat ik voorlopig nog open sta voor vanalles.

[/errug offtopic]

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

[nog offtopicerder]
Sneech:
waarom verander je je ondertitel niet in <? C++ ?> ? :7
[/nog offtopicerder]

Ben ondertussen wel benieuwd hoe drastisch Xenophage zijn ontwerp nu aan moet gaan passen...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Op maandag 01 oktober 2001 15:31 schreef drm
waarom verander je je ondertitel niet in <? C++ ?> ? :7
Omdat dat zou suggereren dat ik:
1. Geen bal van C++ snap, of
2. Twijfel aan C++.
Wat allebei niet zo is.

Verwijderd

Op maandag 01 oktober 2001 15:11 schreef whoami het volgende:
Wel, misschien kan hij er eens over nadenken om die stuff protected te maken ipv private. Dit zou een mooiere oplossing zijn dan het gebruiken van friend functies. Eigenlijk zijn friend functies een beetje tegen de regels van OO.
Wat is er mis met friends? Het gebruik van friend declaraties kan data-hiding juist bevorderen. Ipv. dat je members public of protected maakt, declareer je helper classes of helper functions, die friend zijn van de private data. Het friend keyword geeft je dus meer mogelijkheden tot, en grotere controle over data-hiding. Het is hoe dan ook niet bedoeld om data-hiding "open te breken", daarvoor is de syntax ook niet geschikt.

  • SG
  • Registratie: Januari 2001
  • Laatst online: 13-09 07:59

SG

SG surft naar info hardewaren

Friend functies zorgen voor class afhankelijkheden waardoor die classen niet afzonderlijk opgeleverd kunnen worden want ze zijn afhankelijk van mekaar wat in OOP design ongewenst is.

Maar tussen Classen die vanwege bijvoorbeeld performance Als groep /module worden opgeleverd kan die truc wel gewenst zijn ondanks dat het druist tegen de OOP gedachte omdat deze classen als één abstracte modulen wordt opgeleverd en de friendfuncties op implementatie niveau zich afspeeeld en niet in de interface.

X399 Taichi; ThreadRipper 1950X; 32GB; VEGA 56; BenQ 32" 1440P | Gigbyte; Phenom X4 965; 8GB; Samsung 120hz 3D 27" | W2012SER2; i5 quadcore | Mac mini 2014 | ATV 4g | ATV 4K


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Maar het is heel handig als je gewoon weet dat de gebruiker van je library nooit die members zou gebruiken.
voorbeeld van mezelf:
Ik ben ook bezig met een GUI en mijn treeview is 1 class, CGLGUITreeView, die gebruik maakt van de dataclass CGLGUITreeItem. In deze objecten sla ik runtime rectangles op waar het item zich bevindt, zodat ik sneller kan tekenen. Voor de gebruiker is dit helemaal niet interessant, en get/setters zouden ook alleen maar verwarrend werken.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op maandag 01 oktober 2001 15:10 schreef mbravenboer het volgende:
Jij zult de properties van C# wel mooi vinden :)
Of je pakt C++Builder waar het volgende geen probleem is:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class SomeClass
{
public:
  __property int ReadOnlyByValue     = {read=m_SomeMember};
  __property int ReadOnlyByFunc = {read=GetValue};
  __property int ReadWriteByFunc     = {read=GetValue, write=SetValue};
  __property int ReadWriteCombined   = {read=m_SomeMember, write=SetValue};

private:
  int     GetValue();
  void    SetValue(int p_Value);

  int     m_SomeMember;
};

void MyFunction()
{
SomeClass     MyClass;

MyClass.ReadWriteByFunc     = 256;
MyClass.ReadWriteCombined   = MyClass.ReadOnlyByFunc;
MyClass.ReadWriteByFunc     = MyClass.ReadOnlyByValue;
}

Kun je dus niet alleen intelligente setters gebruiken maar ook intelligente getters (tegenover de standaard inline-const-ref zut :) )

Als je toch bij C++Builder aan het kijken bent neus meteen even in de VCL docs om te zien hoe je een elegant GUI-framework aanmaakt zonder stapels static members of globals. Het is ECHT niet nodig en ECHT niet mooi anders. VCL is ECHT op GUI-framework-gebied de maatstaf van genialiteit. (8>

Professionele website nodig?


Verwijderd

Op maandag 01 oktober 2001 22:50 schreef SuperG het volgende:
Friend functies zorgen voor class afhankelijkheden waardoor die classen niet afzonderlijk opgeleverd kunnen worden want ze zijn afhankelijk van mekaar wat in OOP design ongewenst is.
Hoe zit het dan bv. met iterator classes? Die zijn per definitie afhankelijk van het datatype dat ze itereren. Je kunt de hele implementatie van je datatype-class bloot leggen, zodat die iterator er toegang toe heeft, of je kunt je implementatie verborgen houden (zoals dat hoort) en de iterators als friend declareren.

Het lijkt me idd. wel handig dat de zelfde programmeur die de class schrijft, ook de iterators/helpers voor die class schrijft, en dat ze dus als een module opgeleverd worden.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op dinsdag 02 oktober 2001 00:20 schreef mietje het volgende:
Hoe zit het dan bv. met iterator classes? Die zijn per definitie afhankelijk van het datatype dat ze itereren. Je kunt de hele implementatie van je datatype-class bloot leggen, zodat die iterator er toegang toe heeft, of je kunt je implementatie verborgen houden (zoals dat hoort) en de iterators als friend declareren.
Of class-factory-achtige structuren met protected of private constructors, zoals bijvoorbeeld een HTTP request class die enkel binnen de context van een HTTP session aangemaakt mag worden. Dan kun je in de public constructor van de request vereisen dat er een session wordt meegegeven, maar dan mag iedereen er poep instoppen. Je kunt dan beter de constructor van de request protected maken met een friend declaratie naar de session, en dan de session een CreateRequest method meegeven die hem construeert en initialiseert en een zeker geldige instance of een exception teruggeeft.

In dit voorbeeld mogen de classes nooit afzonderlijk gedistribueerd worden en is het dus geen probleem er een friend-relatie tussen te leggen (net als het iterator-voorbeeld inderdaad).

Friend is overigens wel gevaarlijk als je het als excuus gaat gebruiken om een foute structuur te implementeren: er moet wel degelijk een verdedigbaar nut achterzitten.

Professionele website nodig?


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Topicstarter
Mensen, bedankt voor de replies. Ik heb de oplossing al gelezen:
Op maandag 01 oktober 2001 15:08 schreef Haywire het volgende:
Als ik het goed begrijp ben je bang dat je code voor elke instantie die je aanmaakt in het geheugen terecht komt, dus dat elk object zijn eigen stukje code heeft. Dit is een mooie manier om erover te denken op ontwikkel-niveau (dat is een belangrijk idee van OO programmeren), maar technisch is het heel anders geimplementeerd.
Ik was daar idd bang voor. Maar aangezien het dus blijkbaar niet zo is, kan ik weer rustig ademhalen. 8-) Zoals ik het nu zie valt de hoeveelheid code die elke instance heeft wel mee (nou ja, in vergelijking met mijn basisklasse natuurlijk). Ik kan weer verder. Alhoewel ik nog wel met een probleem zit dat wel een beetje met de topic te maken heeft...

Situatie:
Ik ben dus met een GUI bezig en... wacht dat had ik al gezegd. :P Ik heb dus alle algemene functies in de base class staan, inclusief de functies om events te 'routen'. Het punt is, bij dit routen heb ik variabelen nodig om de status bij te houden (het is een finite state machine, vandaar).

Probleem:
Mijn hersenpijnigende probleem is: omdat die variabelen niet bij alle window classes nodig zijn, zou ik ze dan in een struct moeten zetten en in de class een pointer naar zon struct (die dus desgewenst op NULL gezet kan worden), of moet ik gewoon niet moeilijk doen en die variabelen direct in de class zetten...

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Topicstarter
Fuck dit was een dubbelpost. Ik moet toch es wat minder vensters open hebben :z

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Sneech:
Omdat dat zou suggereren dat ik:
1. Geen bal van C++ snap, of
2. Twijfel aan C++.
Wat allebei niet zo is.
3. Toch weet wat PHP is, ook al zeg je er nee tegen
[/offtopic]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Op dinsdag 02 oktober 2001 08:57 schreef Xenophage het volgende:
Probleem:
Mijn hersenpijnigende probleem is: omdat die variabelen niet bij alle window classes nodig zijn, zou ik ze dan in een struct moeten zetten en in de class een pointer naar zon struct (die dus desgewenst op NULL gezet kan worden), of moet ik gewoon niet moeilijk doen en die variabelen direct in de class zetten...
Werk dan met inheritance :) Definieer het window of schermelement dat de minste variabelen heeft als baseclass, en breidt het vervolgens uit met overerving. Heel simpel voorgesteld:
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
class Rechthoek {
private:
  int _x, _y, _lengte, _breedte;

public:
  virtual void verplaats(int x, int y);
  virtual void vervorm(int lengte, int breedte);

  int x() const { return _x; }
  int y() const { return _y; }
  int lengte() const { return _lengte; }
  int breedte() const { return _breedte; }
};

class Venster : public Rechthoek {
private:
  int     _randtype;
  const char *_titel;

public:
  virtual void zet_randtype(int type);
  virtual void zet_titel(const char* t);

  int randtype() const { return _randtype; }
  const char* titel() const { return _titel; }
};

Hier overerft class Venster alle eigenschappen van class Rechthoek. Je kunt bij een Venster dus net zo verplaats(), vervorm(), x(), y() enz. aanroepen als bij een Rechthoek.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:39

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op maandag 01 oktober 2001 15:31 schreef drm het volgende:
[nog offtopicerder]
Sneech:
waarom verander je je ondertitel niet in <? C++ ?> ? :7
[/nog offtopicerder]
en waarom verander jij je ondertitel niet in "ik ben een aars" :7
Op dinsdag 02 oktober 2001 12:12 schreef mietje een leuk verhaaltje over inheritance...

... en ze leefden nog lang en gelukkig :)
Ik denk dat ie al inheritance gebruikt, hij heeft het immers over een base class.

Xenophage: Als ik je verkeerd begrijp moet je het even zeggen, maar ik denk dat je bedoeling is dat je variabelen over window messages en het routen bij wilt houden tijdens het routen, en dat routen is een recursief proces (begint bij de root, en dan steeds door naar een child van de huidige parent tot je bij de juiste window bent). En je wilt dat child windows die variabelen ook kunnen veranderen als zij het op hun beurt weer routen.

Waarom gooi je die variabelen dan niet in een struct/class, en de root alloceert die struct/class op de stack (gewoon een locale functie variabele dus), en als ie de message route naar een van z'n child windows dan geeft ie een referentie mee naar die struct/class. Dan gebruikt elke child window dezelfde variabelen, terwijl ze niet in de class staan gedefinieerd.

Maar zoals ik al zei, als ik je verkeerd begrijp moet je het even zeggen :)

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.


Verwijderd

Op dinsdag 02 oktober 2001 13:59 schreef OiSyN het volgende:
Ik denk dat ie al inheritance gebruikt, hij heeft het immers over een base class.
Dat snap ik, ik denk alleen dat hij het verkeerd gebruikt. Als ik hem goed begrijp heeft hij zowat alle functionaliteit in de baseclass geimplementeerd, en wil nu minder functionaliteit in de afgeleide classes. Dat is dus precies zoals het niet moet. Een afgeleide class mag geen functionaliteit van de baseclass verbergen, hij mag hem alleen uitbreiden/vervolledigen.

Daarnaast is het natuurlijk een goed idee om een event als een zelfstandig object te structureren, en references naar zo'n object naar de handlers te passen ;)

Verwijderd

Op dinsdag 02 oktober 2001 14:26 schreef mietje het volgende:
Een afgeleide class mag geen functionaliteit van de baseclass verbergen, hij mag hem alleen uitbreiden/vervolledigen.
Mag wel, je kunt een class tenslotte privately inheriten.
Daarnaast is het natuurlijk een goed idee om een event als een zelfstandig object te structureren, en references naar zo'n object naar de handlers te passen ;)
Ik zou het niet zo doen (maar als je met een super-elegante implementatie komt zou je me misschien kunnen overhalen ;)).

Verwijderd

[> dubbelpost <]

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:39

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 02 oktober 2001 15:21 schreef Sneech het volgende:

[..]

Ik zou het niet zo doen (maar als je met een super-elegante implementatie komt zou je me misschien kunnen overhalen ;)).
puur uit interesse, hoe zou jij het dan doen?

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.


Verwijderd

Op dinsdag 02 oktober 2001 15:21 schreef Sneech het volgende:
Mag wel, je kunt een class tenslotte privately inheriten.
En dan misbruik je dus private inheritance. Private inheritance gebruiken is alleen verdedigbaar als je het gebruikt om een virtual baseclass te verbergen, die voor de gebruiker van de afgeleide class niet van belang is of niet toegankelijk mag zijn (als het ware als een private interface in java). Voor alle andere problemen kun je net zo goed aggregatie gebruiken. Het is gewoon de kern van OO-design dat je je baseclasses zo "licht" mogelijk maakt, en in afgeleide classes functionaliteit toevoegt.

Verwijderd

Op dinsdag 02 oktober 2001 16:58 schreef OiSyN het volgende:

[..]

puur uit interesse, hoe zou jij het dan doen?
Hangt er vanaf hoe zo'n event gegenereerd wordt en door wie/wat.

.edit Ik zal ook eens een klein Window-Managertje bakken (win32).
.edit2 Of toch maar niet, Win32 API is vies. :r

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:39

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 02 oktober 2001 17:40 schreef Sneech het volgende:

[..]

Hangt er vanaf hoe zo'n event gegenereerd wordt en door wie/wat.

.edit Ik zal ook eens een klein Window-Managertje bakken (win32).
.edit2 Of toch maar niet, Win32 API is vies. :r
win32 api vind ik niet vies, MFC daarentegen weer wel, hoewel ik het toch gebruik (bij gebrek aan iets beters :))

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.


Verwijderd

Ik heb ooit wel eens een klein OO wrappertje gemaakt voor de Win32 Windowing API, maar daarin vond ik het wel genoeg om een derived class van de base window class gewoon verplicht een LRESULT on_msg (UINT msg,WPARAM arg1, LPARAM arg2) te laten implementeren, waarin ze dan zelf maar die msg mochten switch()-en. Ik had geen behoefte aan een hoger en abstracter event mechanisme.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op dinsdag 02 oktober 2001 18:23 schreef OiSyN het volgende:
win32 api vind ik niet vies, MFC daarentegen weer wel, hoewel ik het toch gebruik (bij gebrek aan iets beters :))
MFC is vies, Win32 API niet vies, VCL is heilig. :Y)


Ennuh over die event targets, de echt nette manier volgens C++ is voor zover ik weet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Button : public Control
{
public:
...
  void            RegisterEventTarget(ButtonEventTarget* p_EventTarget);
...
private:
  ButtonEventTarget*    m_EventTarget;
};

class ControlEventTarget
{
public:
  virtual void      OnMouseOver(Control* p_Control, ...) { }
  virtual void      OnMouseDown(Control* p_Control, ...) { }
...
};

class ButtonEventTarget : public ControlEventTarget
{
public:
  virtual void      OnClick(Button* p_Button) { }
};

Etcetera... kun je inkleden zoals je wilt maar met deze constructie kan de app zelf bepalen welke events ie implementeert.

Tuurlijk is de closure van BCB/VCL mooier en eleganter maar geen standaard C++ jammer genoeg (foei Stroustrup! :'( )

Professionele website nodig?


  • ruuds
  • Registratie: Maart 2001
  • Laatst online: 17-09 14:58
[0.5 offtopic]
Erik jonge, ik zal morgen eens een lap code meenemen, ken je lache (met dat probleem)
[/0.5 offtopic]

:7

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Ik gebruik gewoon:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CBaseWindow
{
...
virtual void OnClick(CMouseData &Mouse);
...
}

void CBaseWindow::OnClick(Mouse)
{
  for_each(child)
  {
     OnClick(Mouse);
  }
}

is dat zo slecht? wel makkelijk iig :p
bij nader inzien besef ik dat ik bij mouse-events hele classes kopieer, omdat ik ze relatief maak...maarja, u get the point :Y)

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Topicstarter
Op dinsdag 02 oktober 2001 14:26 schreef mietje het volgende:

[..]

Dat snap ik, ik denk alleen dat hij het verkeerd gebruikt. Als ik hem goed begrijp heeft hij zowat alle functionaliteit in de baseclass geimplementeerd, en wil nu minder functionaliteit in de afgeleide classes. Dat is dus precies zoals het niet moet. Een afgeleide class mag geen functionaliteit van de baseclass verbergen, hij mag hem alleen uitbreiden/vervolledigen.

Daarnaast is het natuurlijk een goed idee om een event als een zelfstandig object te structureren, en references naar zo'n object naar de handlers te passen ;)
Ik heb een baseclass, met andere/nieuwe functionaliteit in de afgeleide classes. Zoiets als dit dus:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class aw_window
{
public:
  aw_window();
  ~aw_window();

  void init();
  void destroy();

  virtual long wnd_proc(aw_window *src, long msg, long param);
};

class aw_label: public aw_window
{
public:
  aw_label();
  ~aw_label();

  virtual long wnd_proc(aw_window *src, long msg, long param);
};

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?

Pagina: 1