Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

01.12.2015, 23:44

virtual/überladene Methode

Guten Abend,

ich habe gerade folgendes Konstrukt.

C-/C++-Quelltext

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
#include <map>

template <class T>
class Foo
{
public:
    virtual void test(const std::pair<T, T>& _value) = 0;
    void test(const T& _1, const T& _2)
    {
        test(std::pair<T, T>(_1, _2));
    }
};

template <class T>
class Bar : public Foo<T>
{
    void test(const std::pair<T, T>& _value) override
    {
        // do someting
    }
};

int main()
{
    Bar<int> bar;
    bar.test(1, 2);
}

compile me

Sieht eigentlich recht einfach aus und meinem Verständnis nach, sollte das auch wunderbar compilen. Aber er meckert, dass die Funktion nur ein Argument erwartet und nicht 2.
Jedoch sieht man in Foo ganze deutlich, dass die Methode existiert. Rufe ich die Methode per bar.Foo<int>::test(1,2); auf, funktioniert es wunderbar.
Die Frage, die ich mir jetzt stelle, warum ist das so und wie kann ich das beheben, außer diese Methode in jeder Subclass implementieren zu müssen.

mfg

EDIT: liegt übrigens nicht am Template, das habe ich gerade ohne Erfolg entfernt.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

01.12.2015, 23:50

Die Methode test() in der abgeleiteten Klasse überschreibt nicht nur die test() der Basis, sondern shadowed auch den Namen test... ;)

C-/C++-Quelltext

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
#include <map>

template <class T>
class Foo
{
public:
    virtual void test(const std::pair<T, T>& _value) = 0;
    void test(const T& _1, const T& _2)
    {
        test(std::pair<T, T>(_1, _2));
    }
};

template <class T>
class Bar : public Foo<T>
{
public:
    using Foo<T>::test;  // explizit alles mit Namen test aus der Basis reinholen
    
    void test(const std::pair<T, T>& _value) override
    {
        // do someting
    }
};

int main()
{
    Bar<int> bar;
    bar.test(1, 2);
}

3

01.12.2015, 23:53

Komisch das mir das bisher nicht aufgefallen ist. Kann mir nicht vorstellen, dass das hier das erste mal ist, dass ich sowas benutze...

Wundert mich aber, das hier nicht die komplette Signatur beachtet wird, sondern nur der Name. Gibt es dafür sinnvolle Anwendungsfälle oder warum wurde das so designed?

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

4

02.12.2015, 08:47

Nö, shadowed nicht. Würde ich behaupten. Die Basisklasse ist doch klar definiert, die Signatur identisch, und schlussendlich würde der Compiler dank override meckern, wenn das nur ein Shadowing wäre. Ich gehe mal von C++11 aus, korrekt? Weil VC++ auch vorher schon override unterstützt hat, da aber mit subtil abweichender Funktionsweise, wenn ich mich recht erinnere.

Für mich sieht das eher danach aus, als hättest Du eine schlichte Parameter-Verwirrung. Die Funktion erwartet *ein* Argument, nämlich ein std::pair. Du gibst ihm *zwei* Argumente, nämlich zwei int. Im einfachsten Fall würde eine initializer_list das Problem lösen, also ein schlichtes:

Quellcode

1
bar.test( {1, 2} );


Ohne es getestet zu haben. Wenn's nicht geht, dann halt explizit std::make_pair(1, 2).

[edit] Habe gerade mal Deinen Link ausprobiert: Du hast außerdem das Problem, dass die Funktion Bar<T>::test() nicht public ist. Wenn ich das in Deinem Code-Beispiel korrigiere und ein {} um die Aufrufparameter setze, kompiliert und läuft es sauber.

[edit] Ups, alles Quatsch. Deine Basisklassen-Funktion nimmt zwei ints, die Funktion in Deiner abgeleitete Klasse ein std::pair<>. Das ist in der Tat ein ganz banales Shadowing.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Schrompf« (02.12.2015, 09:00)


Werbeanzeige