Toon posts:

[c++ / java] hoe een methode final te krijgen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi iedereen,

Stel ik heb de volgende java klasse:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class MyClass {
   public final int getSomeStupidValue() {
     return _myValue;
   }
 
   public abstract int doSomething();
}

In C++ ziet er dat ongeveer zo uit:

class MyClass {
   public:
     int getSomeStupidValue() { return _myValue; }
     virtual int doSomething() {} = 0; // declare as pure virtual
};

Nu is mijn probleem... Dat de eindgebruiker... De subklasse die erft van mijn klasse nog altijd de methode getSomeStupidValue() kan herdefinieeren... (in het C++ voorbeeld dan). In C++ bestaat er geen "final" keyword....

Hoe kan ik er nu toch voor zorgen dat de eindgebruiker niet de methode getSomeStupidValue() kan herdefinieeren?

Bedankt voor jullie meedenkwerk!

Harm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Dat kan niet in C++, omdat je er in zo'n geval voor kan kiezen (zoals je nu ook hebt gedaan) om zo'n methode statisch te definiëren. Je kunt er dus altijd van op aan dat jou methoden de door jou gedefinieerde methode pakken en niet die van de gebruiker. In C/C++ staat het gebruikers doorgaans vrij om de werking van een applicatie te verneuken als ze dat ECHT willen.

  • Stephan Oudmaijer
  • Registratie: Oktober 2000
  • Laatst online: 16-08-2023
const achter de functie zetten zorgt er toch voor dat je een functie niet mag overwritten?

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op donderdag 28 maart 2002 21:41 schreef CK het volgende:
const achter de functie zetten zorgt er toch voor dat je een functie niet mag overwritten?
Nee dit betekent dat de functie het object niet mag muteren.

Maar ik vraag me eigenlijk ook af of er een goed argument is voor datgene wat je wil. Een programmeur wordt in C++ idd zoveel mogelijk vrijgelaten. Als je echt niet wil dat een bepaalde methode anders wordt gebruikt kan je 'm private maken, dan weet je in ieder geval dat wanneer jij het aanspreekt het doet wat het moet doen.

Maar deriven is ook vaak een manier om de functionaliteit van de bestaande classe uit te breiden of te verbeteren, waarom zou je dat niet willen?

Verwijderd

Topicstarter
Op donderdag 28 maart 2002 23:37 schreef Orphix het volgende:

[..]

Nee dit betekent dat de functie het object niet mag muteren.

Maar ik vraag me eigenlijk ook af of er een goed argument is voor datgene wat je wil. Een programmeur wordt in C++ idd zoveel mogelijk vrijgelaten. Als je echt niet wil dat een bepaalde methode anders wordt gebruikt kan je 'm private maken, dan weet je in ieder geval dat wanneer jij het aanspreekt het doet wat het moet doen.

Maar deriven is ook vaak een manier om de functionaliteit van de bestaande classe uit te breiden of te verbeteren, waarom zou je dat niet willen?
Tja, waarom bestaat er een final keyword in java ;)

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

curry684

left part of the evil twins

Op donderdag 28 maart 2002 21:35 schreef Soultaker het volgende:
Dat kan niet in C++, omdat je er in zo'n geval voor kan kiezen (zoals je nu ook hebt gedaan) om zo'n methode statisch te definiëren. Je kunt er dus altijd van op aan dat jou methoden de door jou gedefinieerde methode pakken en niet die van de gebruiker.
Wat echter niet waterdicht is zoals bij de functie 'doSomething', die per definitie virtual blijft tot in lengte van dagen.

Soms kan het inderdaad best handig zijn als je binnen je eigen inheritancetree een functie virtual kan maken voor 2 of 3 overervingen om 'm dan uiteindelijk 'final' te maken.
In C/C++ staat het gebruikers doorgaans vrij om de werking van een applicatie te verneuken als ze dat ECHT willen.
Idd, eigenlijk tegelijkertijd een zwak punt en een erg sterk punt van de taal.

Als je eindgebruiker iets stoms doet is het z'n eigen schuld, maar misschien doet ie juist wel iets heel intelligents. You never know ;)

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Op vrijdag 29 maart 2002 17:54 schreef curry684 het volgende:
Wat echter niet waterdicht is zoals bij de functie 'doSomething', die per definitie virtual blijft tot in lengte van dagen.
Dat is niet waar. Je kan nog steeds in klas X de virtuele methode X::doSomething() aan te roepen, zodat ook echt de in X gedefinieerde methode wordt gebruikt en niet een andere (zoals 'by default' zou gebeuren). Je kan dus nog steeds de integriteit van jou eigen klassen garanderen. Dan kun je die methode weliswaar niet meer virtueel gebruiken, maar als je de garantie wilt dat jou code uitgevoerd wordt, kan dat toch al niet (zie hieronder).
Soms kan het inderdaad best handig zijn als je binnen je eigen inheritancetree een functie virtual kan maken voor 2 of 3 overervingen om 'm dan uiteindelijk 'final' te maken.
Daar ben ik het niet mee eens. Als het voor jou handig is om te erven, kan dat voor een ander ook handig zijn. Uiteraard mag je best een waarschuwing bij je methode plaatsen - je kan toch geen methoden overriden zonder eerst uit te zoeken wat ze doen. Ik zie geen reden waarom je de gebruiker zou willen beperken, als dit zich niet terugvertaald in het voorkomen van fouten. Het is immers niet mogelijk dat een gebruiker 'per ongeluk' een nieuwe klasse maakt en daarin een van jou methoden override.

Verder is het final maken helemaal geen garantie dat alles goed gaat, want niets weerhoud mij ervan om van de superklasse van de klasse met de final method af te leiden, waardoor ik alsnog mijn eigen code door jou methoden kan laten uitvoeren.
Idd, eigenlijk tegelijkertijd een zwak punt en een erg sterk punt van de taal.
Klopt; waar de balans ligt verschilt dan ook per ontwikkelaar. Ik neig enigszins naar het 'sterke punt', zoals je merkt. ;)
Als je eindgebruiker iets stoms doet is het z'n eigen schuld, maar misschien doet ie juist wel iets heel intelligents. You never know ;)
So true. ;) Ik zou daarom zeggen: focus op heldere code, zodat de kans klein wordt dat gebruiker per ongelijk dingen doet die niet goed zijn, maar maak het hem niet onmogelijk om dingen te hacken.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op vrijdag 29 maart 2002 19:55 schreef Soultaker het volgende:

Dat is niet waar. Je kan nog steeds in klas X de virtuele methode X::doSomething() aan te roepen, zodat ook echt de in X gedefinieerde methode wordt gebruikt en niet een andere (zoals 'by default' zou gebeuren). Je kan dus nog steeds de integriteit van jou eigen klassen garanderen. Dan kun je die methode weliswaar niet meer virtueel gebruiken, maar als je de garantie wilt dat jou code uitgevoerd wordt, kan dat toch al niet (zie hieronder).
tenzij je natuurlijk zelf subklassen hebt gedefinieerd waarvan wel de functie aangeroepen moet worden. Je weet dan in de baseklasse niet welke functie je moet hebben, dus je kunt het ook niet forceren (of natuurlijk vies eromheen gaan coden door te detecteren wat voor klas het nou eigenlijk is, maar dan kun je ze net zo goed niet virtual maken :))

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.


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

curry684

left part of the evil twins

Op vrijdag 29 maart 2002 19:55 schreef Soultaker het volgende:
Dat is niet waar. Je kan nog steeds in klas X de virtuele methode X::doSomething() aan te roepen, zodat ook echt de in X gedefinieerde methode wordt gebruikt en niet een andere (zoals 'by default' zou gebeuren). Je kan dus nog steeds de integriteit van jou eigen klassen garanderen.
Mag jij mij vertellen hoe ik dat in het specifiek aangehaalde voorbeeld van razor_harm moet doen:
code:
1
virtual int doSomething() = 0; // declare as pure virtual

Die is wat tricky hoor ;)


(ps. ik heb die 2 foute implementatie-accolades wel even geschrapt)

Professionele website nodig?


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

curry684

left part of the evil twins

Op vrijdag 29 maart 2002 22:22 schreef OiSyN het volgende:
(of natuurlijk vies eromheen gaan coden door te detecteren wat voor klas het nou eigenlijk is, maar dan kun je ze net zo goed niet virtual maken :))
Ik kan hier zo snel niet eens een waterdichte methode voor bedenken... :?

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

nou ik bedoelde zeg maar zoiets:
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
39
40
41
42
43
44
45
class Base
{
public:
    void functie ();
    virtual int getType ();

    const int TYPE = 0;
};

class A : public Base
{
public:
    void functie ();
    int getType ();

    const int TYPE = 1;
};

class B : public Base
{
public:
    void functie ();
    int getType ();

    const int TYPE = 2;
};


void bla (Base * b)
{
    switch (b->getType ())
    {
    case Base::TYPE:
      b->functie ();
      break;

    case A::TYPE:
      ((A *)b)->functie ();
      break;

    case B::TYPE:
      ((B *)b)->functie ();
      break;
    }
}

idd niet geheel waterdicht, en erg vies, maar de implementatie van een door de gebruiker gedefinieerde subklasse wordt iig nooit aangeroepen :)

(misschien dat je met RTTI een beter systeem kunt bedenken, maar daar ben ik niet zo'n voorstander van)

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.


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

curry684

left part of the evil twins

Op zaterdag 30 maart 2002 21:49 schreef OiSyN het volgende:
idd niet geheel waterdicht, en erg vies, maar de implementatie van een door de gebruiker gedefinieerde subklasse wordt iig nooit aangeroepen :)
En compleet niet wat je voorstelde, namelijk dat functie() virtual moest zijn :)

Het lukt echt niet als ie virtual is hoor...

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op zondag 31 maart 2002 22:50 schreef curry684 het volgende:

[..]

En compleet niet wat je voorstelde, namelijk dat functie() virtual moest zijn :)

Het lukt echt niet als ie virtual is hoor...
tuurlijk wel (ik had m expres niet virtual gemaakt omdat dat gewoon niet nodig was). Je kunt een functieaanroep zo forceren:
code:
1
b->Base::functie ();

dan roept ie altijd Base::functie () aan, ongeacht of ie nou door een subclass geoverride is of niet :)

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.

Pagina: 1