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

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

11

30.08.2012, 16:39

Tja die Frage lässt sich rein logisch beantworten: entweder man kann über implizites Wissen unterscheiden (z.B. Kontainer A hat nur Objekte von genau einem Typ) oder eben über eine explizite Information wie eine type_id oder RTTI. Sprich einen Tod muss du sterben, außer ich habe etwas komplett übersehen.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

12

31.08.2012, 00:44

Nachdem ich die Boost Doc gesehen habe weis ich endlich wofür templates gut sind :thumbsup:

Meine Lösung wie man eine neue Klassen Instanz mit nur einem String erstellen kann (ganz ohne RTTI):

PS: Der Code ist nur proof of concept daher nicht wirklich schön :/

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// serial.h
#pragma once

#include <string>
#include <map>

class Entry
{
public:
    virtual void* Get() = 0;
};

template<class T> 
class register_type : public Entry 
{
public: 
    virtual void* Get() 
    { 
        return new T; 
    } 
}; 

std::map<std::string, Entry*> map;

template<class T>
void addType(std::string name)
{
    map[name] = new T;
}

template<class T>
T* getType(std::string name)
{
    return (T*)map[name]->Get();
}

template<class T>
class register_invoker
{
public:
    register_invoker(std::string name)
    {
        addType<T>(name);
    }
};


template<class T> 
struct init_invoker;

#define REGISTER_TYPE(T,Name) \
    template<> \
    struct init_invoker<T> { \
        static register_invoker<register_type<T>> const & invoker; \
    }; \
    register_invoker<register_type<T>> const & init_invoker<T>::invoker = \
    register_invoker<register_type<T>>(Name)


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
37
38
//Test1.h
#pragma once

#include "serial.h"
#include <Windows.h>

class Base
{
public:
    virtual void MSGBOX()
    {
        MessageBoxA(0,"Base","",0);
    }
};

REGISTER_TYPE(Base,"base");

class Kind1 : public Base
{
public:
    virtual void MSGBOX()
    {
        MessageBoxA(0,"Kind1","",0);
    }
};

REGISTER_TYPE(Kind1,"kind1");

class Kind2 : public Kind1
{
public:
    virtual void MSGBOX()
    {
        MessageBoxA(0,"Kind2","",0);
    }
};

REGISTER_TYPE(Kind2,"kind2");

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// main.cpp
#include <Windows.h>

#include "Test1.h"

int CALLBACK WinMain(HINSTANCE h, HINSTANCE hp, char* c, int cmd)
{
    Base* b = new Base;
    Kind1* k1 = new Kind1;
    Kind2* k2 = new Kind2;

    b->MSGBOX();
    k1->MSGBOX();
    k2->MSGBOX();

    // name aus stream ziehen
    b = getType<Base>("kind2");
    b->MSGBOX();

    return 0;
}


Ausgabe ist:

Base
Kind1
Kind2
Kind2
greate minds discuss ideas;
average minds discuss events;
small minds discuss people.