[C++] C#-like override in C++

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Mnstrspeed
  • Registratie: Oktober 2007
  • Laatst online: 03:00
Waarschijnlijk weer een beginnersvraag, maar googlen heeft tot nu toe weinig tot niets opgeleverd :/

Ik wil de method van een base class volledig vervangen door een gelijknamige method in mijn derived class, zodat wanneer ik vanuit de constructor van de base class de method aanroep, hij de method van de derived class pakt en niet die van de base class. In C# kon dit altijd makkelijk via de override modifier.

C#:
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
using System;

public class Base
{
    public Base()
    {
        Console.WriteLine("Base.Base");
        this.Update();
    }

    protected virtual void Update()
    {
        Console.WriteLine("Base.Update");
    }
}

public class Derived : Base
{
    public Derived()
    {
        Console.WriteLine("Derived.Derived");
    }

    protected override void Update()
    {
        Console.WriteLine("Derived.Update");
        base.Update();
    }

    public static void Main()
    {
        Derived d = new Derived();
    }
}


De output hierbij is dus

code:
1
2
3
4
Base.Base
Derived.Update
Base.Update
Derived.Derived


Hoe zou ik in C++ een vergelijkbare werking kunnen krijgen?

Alvast bedankt :)

Ehhh wat?


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Erg lang zal je niet gezocht hebben ;) Zoek maar op "C++ virtual function"

Acties:
  • 0 Henk 'm!

  • Mnstrspeed
  • Registratie: Oktober 2007
  • Laatst online: 03:00
Ook op gezocht, ja, maar niet wat ik zoek.

C++:
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
#include <iostream>
#define Out(x) std::cout << x << std::endl;

class Base
{
public:
    Base()
    {
        Out("Base::Base");
        Update();
    }

    virtual void Update()
    {
        Out("Base::Update");
    }
};

class Derived : public Base
{
public:
    virtual void Update()
    {
        Out("Derived::Update");
    }
};

int main()
{
    Derived d;
    std::cin.get();

        return 0;
}


Met de output:
Base::Base
Base::Update
Wat dus niet de bedoeling is, aangezien ik juist Derived::Update vanuit Base::Base wil aanroepen ;)

Ehhh wat?


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Dat is omdat je het in een constructor doet. Eerst wordt Base volledig geinstantieerd, voordat de constructor van Derived verder wordt uitgevoerd. Op het moment dat de costructor voor Base hier dus draait, bestaat Derived nog niet, en wijst Update() naar Base::Update. zie ook http://www.artima.com/cppsource/nevercall.html

Wat C# hier doet lijkt me erg riskant...

[ Voor 6% gewijzigd door Zoijar op 19-07-2009 16:42 ]


Acties:
  • 0 Henk 'm!

  • Stray
  • Registratie: Juli 2003
  • Laatst online: 08-09 22:54
Indien je in de derived class een functie definieerd met dezelfde signature zal is hij overriden.
Alleen moet je in dit geval opletten met polymorphisme en eigenlijk is het een bad programming practice om non-virtual member-methods te overriden.
Indien je zelf de code van de base class kan aanpassen meot je de functie virtual maken, zoals Zoilar al heeft aangegeven.

Acties:
  • 0 Henk 'm!

  • Mnstrspeed
  • Registratie: Oktober 2007
  • Laatst online: 03:00
Bedankt voor de opheldering, nu zie ik het ook :)

In mijn echte base class riep ik bovendien ook nog eens Base::Update aan ipv gewoon Update, waardoor hij automatisch al naar de base method ging. Logisch dus dat het niet werkte :o

Dit is dus de goede, niet-riskante versie van hoe het zou moeten?

C++:
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
#include <iostream>
#define Out(x) std::cout << x << std::endl;

class Base
{
public:
    Base()
    {
        Out("Base::Base");
    }

    void Create()
    {
        Update();
    }

    virtual void Update()
    {
        Out("Base::Update");
    }
};

class Derived : public Base
{
public:
    void Update()
    {
        Out("Derived::Update");
    }
};

int main()
{
    Derived d;
    d.Create();

    std::cin.get();
}

Ehhh wat?


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Dat zou volgens mij wel moeten werken, ja. Als je met inheritance werkt in C++ kan je wel beter met pointers of references werken, anders kan je problemen krijgen met kopieen. Zoek maar op "object slicing"

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:02
Stray678 schreef op zondag 19 juli 2009 @ 16:39:
Indien je zelf de code van de base class kan aanpassen meot je de functie virtual maken, zoals Zoilar al heeft aangegeven.
Maar dat was hier niet de fout, de fout was dat een virtual functie in een constructor/destructor van een base class niet doet wat de TS wil.

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