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

22.09.2013, 19:31

Iterieren durch einen void Pointer

Hi!
Ich habe ein kleines Problem, welches ich nicht wirklich (gut) lösen kann. Mir fehlt da wohl fundamentales Grundlagenwissen... :S
Egal, mein Problem wird am besten von einem Sourcecode beschrieben:

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
void Stream::append(const void* data, std::size_t sizeInBytes)
{
    if (data && (sizeInBytes > 0))
    {
        std::size_t start = m_data.size();
        m_data.resize(start + sizeInBytes);
        std::memcpy(&m_data[start], data, sizeInBytes);
    }
}

//Foo, Definition der abgeleiteten, rein virtuellen Funktion "Update"
void Foo::Update(const Stream& stre)
{
    Stream strE = stre;

    void* p = const_cast<void*>(strE.getData());
    const std::size_t size = strE.getDataSize();

    /*Wie nun auf die Daten zugreifen?*/    
}

//Irgendwo; std::vector<std::shared_ptr<Foo>> m_irgendwas
{
    Stream stream;
    for(auto at = objekte.begin(); at != objekte.end(); ++at)
    {
        stream.clear();
        stream.append(anderesObjekt, sizeof(anderesObjekt));

        for(auto it = irgendwas.begin(); it != irgendwas.end(); ++it)
            stream.append(&**it, sizeof(**it));
        at->update(stream);
    }
}

Das Hauptproblem ist eigentlich, dass dort Objekte drin sind, die nicht von einer gemeinsamen Grundklasse abstammen.
Zur Lösung hatte ich mir überlegt noch eine Grundklasse zu machen, wo ich lediglich eine Variable habe, die mir mitteilt, von welchen folgenden Basisklassen geerbt wird, sodass ich sicher hin und her casten und schließlich überhaupt iterieren kann. Ich möchte wissen, ob dieser Weg "gut" ist oder ob euch was besseres einfällt. Ich bin mir einfach unsicher. ^^

MfG
Check

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

22.09.2013, 19:42

Stichworte:
- Interface
- Polymorphie

void* deutet auf einen argen Design-Fehler hin. Casting übrigens auch irgendwo, speziell dann, wenn es verschiedene Parent-Klassen gibt, in die Du casten willst.
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

3

22.09.2013, 19:43

Das Hauptproblem ist eigentlich, dass dort Objekte drin sind, die nicht von einer gemeinsamen Grundklasse abstammen.

Wieso?

4

22.09.2013, 19:56

Der Stream gibt mir seine Daten nun mal als const void*....

Wieso? Keine Ahnung. Deswegen die von mir schon angedachte Änderung dahin, dass alle von einer Grundklasse erben.

MfG
Check

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

22.09.2013, 20:21

Da kommen komplett alignete Instanzen von Klassen aus einem Stream? Das ist... merkwürdig.
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]

6

22.09.2013, 20:48

Danke.

MfG
Check

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

23.09.2013, 06:47

Man sollte mit Casts aber unbedingt aufpassen. Nimmt man nicht den richtigen - und in diesem Fall spreche ich von einem dynamic_cast - Typ von Cast, landet man ganz schnell irgendwo verkehrt und die vtables sind im Arsch. Mir persönlich noch nicht passiert, soll unter GCC aber wohl vorkommen, er springt da beim Cast mehrere Bytes umher. Details kennt vielleicht dot, das Thema dazu habe ich leider nicht mehr im Kopf.
Es klingt für mich dennoch nach einem sehr schlechten Konzept. Wenn es hier um Serialisierung geht, sollte man über eine Factory und ein entsprechendes Dispatch nachdenken. Die binären Daten einfach nur zu casten halte ich jedenfalls für völlig falsch bei Serialisierung. Da sollte eine vernünftige Deserialisierung stattfinden, allein schon für Kompatibilität verschiedener Versionen der Daten oder Datenstrukturen mit optionalen Membern und Längen.
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]

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »BlueCobold« (23.09.2013, 06:58)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

23.09.2013, 09:31

Ein Downcast (Cast von Basis nach Abgeleitet) ist praktisch immer Symptom eines Designproblems. static_cast reicht allerdings in der Regel, wenn man keinen runtime Check braucht, um die evtl. nötige Pointerschubserei kümmert sich der Compiler automatisch, sofern du ihm eine Chance dazu gibst (von Basis nach void* und dann von void* nach Abgeleitet wird z.B. nicht funktionieren; wenn schon, dann direkt von Basis nach Abgeleietet). Lediglich im Zusammenhang mit Mehrfachvererbung und virtuellen Basisklassen gibt es manche Fälle, die sich tatsächlich nur mit dynamic_cast behandeln lassen. Generell ist void* in C++ eher zu vermeiden, auch wenn es tatsächlich manchmal Situationen gibt, in denen void* Teil einer sauberen Lösung sein kann. Selbst diese Situationen sind wohl noch häufiger als die, in denen ein Downcast nicht ein Problem anzeigt...

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »dot« (23.09.2013, 09:44)


Werbeanzeige