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

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

1

23.08.2014, 18:56

C++ auf bestimmte Basisklasse prüfen

Hallo! Ich möchte gerne zur Compiler-Zeit prüfen, ob eine Klasse von einer bestimmten Klasse geerbt hat.
Pseudocode:

Quellcode

1
2
3
4
5
6
7
template <class T>
void Foo(T* element)
{
   #if("element" doesn't have base "BaseClass")
       #error "Nope!"
   #endif
}

Gibt es da eine Möglichkeit? dynamic_cast ist erst zur Laufzeit.
Danke im Voraus.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

LukasBanana

Alter Hase

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

2

23.08.2014, 19:04

Habs noch nie benutzt, aber schau dir das mal an: std::is_base_of.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

23.08.2014, 21:08

Was genau möchtest du damit erreichen?

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

4

23.08.2014, 21:51

"std::is_base_of" funktioniert aber natürlich nicht mit dem Präprozessor.
Wie du eigentlich wissen solltest ist der Präprozessor nur eine Textersetzungsmaschine und weiß deshalb noch überhaupt nichts von Klassen oder gar Vererbung.

Mir sieht es stark so aus als möchte er eine Fehlermeldung für den Fall ausgeben, dass ein Templateargument falsch angegeben wurde.
Für den Fall das ich richtig liege, solltest du dir zusätzlich mal "static_assert" anschauen...

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

5

24.08.2014, 02:02

Danke ich arbeite mich mal durch.
@dot:
SpieleProgrammierer hat's gesagt ;)

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

24.08.2014, 09:29

@dot:
SpieleProgrammierer hat's gesagt ;)

Nun, die eigentliche Frage ist: Wieso genau musst du sicherstellen, dass ein Template Argument von einer bestimmten Basisklasse erbt?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

24.08.2014, 10:12

Um die Frage mal fortzuführen: Wozu dann überhaupt noch ein Template, wenn man eh auf einem gemeinsamen Interface/einer Basisklasse operieren kann?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

24.08.2014, 11:59

Bingo

Klingt mir irgendwie so, als ob du eigentlich

C-/C++-Quelltext

1
2
3
4
void Foo(ElementBase* element)
{
  ...
}

willst und nicht

C-/C++-Quelltext

1
2
3
4
5
template <class T>
void Foo(T* element)
{
  ...
}

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

9

24.08.2014, 12:29

Und wenn man von dieser Basis Klasse eine spezifische Unterklasse benötigt, habe ich mir (u.a. für mein Compiler Projekt) ein Pattern der folgenden Art angewöhnt:

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
31
32
33
34
35
36
class ChildClassFoo;
class ChildClassBar;

class BaseClass {
public:
    virtual ChildClassFoo* isChildFoo() {
        return nullptr;
    }

    virtual ChildClassBar* isChildBar() {
        return nullptr;
    }
};

class ChildClassFoo : public BaseClass {
public:
    ChildClassFoo* isChildFoo() override {
        return this;
    }
};

class ChildClassBar : public BaseClass {
public:
    ChildClassBar* isChildBar() override {
        return this;
    }
};

void foo(BaseClass* bc) {
    if (!bc)
        return;

    if (ChildClassBar* cb = bc->isChildBar()) {
        // Do something with cb
    }
}

Vllt. hilft das ja jemanden. :) Man kann natürlich auch dynamic_cast verwenden, keine Frage. ;)
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

10

24.08.2014, 12:31

Ja das ist richtig, dass es so geht. Aber das geht nur bei Zeigern.
Bei so etwas:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
void Bar()
{
    Child child; // : public ElementBase
    Foo(child);
}
void Foo(ElementBase base)
{
}

Bekomme ich doch ObjectSlicing? Und immer von dem Zeiger der Basisklasse auf die Childklasse zu casten, finde ich schlechten Stil.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Werbeanzeige