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

rewb0rn

Supermoderator

  • »rewb0rn« ist der Autor dieses Themas

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

1

27.08.2005, 20:20

Immer noch Problem mit Template Klasse

Hi also ich habe immer noch ein Problem mit meinem Speichermanager. Hier ist der Code:

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
template <class T>
struct STListEntry
{
    T*                      Object;
    char*                   pcObjectPath;
    char*                   pcAddInf1;
    char*                   pcAddInf2;

    inline STListEntry() {Object = NULL; pcObjectPath = NULL, pcAddInf1 = NULL, pcAddInf2 = NULL;}
    inline ~STListEntry() {delete Object; delete[] pcObjectPath; delete[] pcAddInf1; delete[] pcAddInf2;}
};

template <class T>
class TMemoryManager
{
private:
    static STListEntry<T>*  pObjectList;
    static int              iObjectCount;

protected:
    static T* GetListMember(char* pcObjectPath, char* pcAddInf1, char* pcAddInf2)
    {
        //Die Liste durchgehen

        for (int i = 0; i < iObjectCount; i++)
            if (pObjectList[i].pcObjectPath == pcObjectPath)
                //Sind die ZusatzInfos identisch, bzw egal (== NULL)

                if ((pcAddInf1 == NULL || strcmp(pObjectList[i].pcAddInf1, pcAddInf1) == 0)
                    && (pcAddInf2 == NULL || strcmp(pObjectList[i].pcAddInf2, pcAddInf2) == 0))
                    //dann gefundenes Objekt zurückgeben

                    return pObjectList[i].Object;
        //ansonsten kein Objekt übereinstimmend:

        return NULL;
    }

public:
    static void InsertEntry(T* Object, char* pcObjectPath, char* pcAddInf1, char* pcAddInf2)
    {
        iObjectCount++;
        pObjectList = tbMemReAlloc(pObjectList, iObjectCount*sizeof(STListEntry<T>));
        pObjectList[iObjectCount].Object = Object;

        //Zuweisen der Strings:

        pObjectList[iObjectCount].pcObjectPath = new char[255];
        pObjectList[iObjectCount].pcAddInf1 = new char[255];
        pObjectList[iObjectCount].pcAddInf2 = new char[255];
        strcpy(pObjectList[iObjectCount].pcObjectPath, pcObjectPath);
        strcpy(pObjectList[iObjectCount].pcAddInf1, pcAddInf1);
        strcpy(pObjectList[iObjectCount].pcAddInf2, pcAddInf2);
    }

    //Setzt vorraus, dass die chars zugewiesenen Speicher haben, im Normalfall char* = new char[255]

    static void GetChars(T* Object, char* pcObjectPath, char* pcAddInf1, char* pcAddInf2)
    {
        for (int i = 0; i < iObjectCount; i++)
            if (Object == pObjectList[i].Object)
            {
                strcpy(pcObjectPath, pObjectList[i].pcObjectPath);
                strcpy(pcAddInf1, pObjectList[i].AddInf1);
                strcpy(pcAddInf2, pObjectList[i].AddInf2);
                break;
            }
    }

    static void Release()
    {
        tbMemFree(pObjectList);
    }
};

//*******************************************************

class CEffectManager : public TMemoryManager<tbEffect>
{
public:
    static tbEffect* GetEntry(char* pcObjectPath, char* pcAddInf1, char* pcAddInf2)
    {
        tbEffect* Effect = GetListMember(pcObjectPath, pcAddInf1, pcAddInf2);
        if (Effect == NULL)
        {
            Effect->Init(pcObjectPath);
            InsertEntry(Effect, pcObjectPath, pcAddInf1, pcAddInf2);
        }
        return Effect;
    }
};


Und zwar wird folgender Fehler ausgegeben:

Quellcode

1
2
3
4
5
l:\Projekte\SB\Source Code\SphereBots Static Classes.h(196): error C2440: '=' : cannot convert from 'void *' to 'STListEntry<T> *'
        with
        [
            T=tbEffect
        ]

Er bezieht sich auf die Zeile 2 der Funktion InsertEntry, in der steht

C-/C++-Quelltext

1
pObjectList = tbMemReAlloc(pObjectList, iObjectCount*sizeof(STListEntry<T>));



Funktionsweise: Die Funktion CEffectManager::GetEntry prüft ob in der Basisklasse der gewünschte Effekt eingetragen ist, und wenn nicht dann erstellt sie einen neuen und trägt ihn ein.

Der Fehler kommt nicht wenn ich die Funktion InsertEntry aus CEffectManager::GetEntry einfach lösche.. Ich hab nicht genügend Erfahrung mit templates, hat jemand eine Idee?

rewb0rn

Supermoderator

  • »rewb0rn« ist der Autor dieses Themas

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

2

27.08.2005, 21:30

ok hat sich geklärt ich war einfach nur blöd und habe vergessen eine Typkonvertierung vorzunehmen... so muss es heißen:

C-/C++-Quelltext

1
pObjectList = (STListEntry<T>*)tbMemReAlloc(pObjectList, iObjectCount*sizeof(STListEntry<T>));


Falls sich schon jemand den Kopf zerbrochen hat, tut mir leid :huhu:

Anonymous

unregistriert

3

27.08.2005, 22:58

Normalerweise verwendet man in C++ new zum Speicheranfordern, wenn man keine PODs hat (und selbst da schadet es nicht). Und wieso verwendest du nicht einfach nen std::vector< STListEntry< T > > oder std::list< STListEntry< T > >?

rewb0rn

Supermoderator

  • »rewb0rn« ist der Autor dieses Themas

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

4

27.08.2005, 23:56

Du hast das zugrunde liegende System nicht verstanden ;)
Mit new würde zwar neuer Speicher reserviert, aber der alte verloren gehen. Die Listengröße ändert sich ja ständig und es muss gewährleistet werden, dass die alten Informationen beibehalten werden, was mit der Methode tbMemReAlloc gewährleistet wird. Zum zweiten kann ich nichts sagen, weil ich das nicht kenne, aber was hat ein Vektor damit zu tun?

Anonymous

unregistriert

5

28.08.2005, 00:37

Ich hab dein Zugrunde liegendes System durchaus verstanden, aber du kopierst hier den Speicher von Objekten mit tbMemReAlloc und umgehst damit den Konstruktor.

std::vector ist ein dynamisches array

rewb0rn

Supermoderator

  • »rewb0rn« ist der Autor dieses Themas

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

6

28.08.2005, 00:39

Ja das mit dem Konstruktor stimmt, das stört mich auch, aber mit new würde es wie gesagt nicht gehen...

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

7

28.08.2005, 00:46

mit new würde es schon gehen. Einfach den Inhalt zwischenspeichern. So bist du auf jedenfall auf der sicheren Seite.

rewb0rn

Supermoderator

  • »rewb0rn« ist der Autor dieses Themas

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

8

28.08.2005, 01:31

Wenn ich den Inhalt zwischenspeichern würde hätte ich wieder n Problem mit der Geschwindigkeit.. Was ich mir jetzt noch überlegt hätte wäre n Doppelpointer, so könnte ich einfach das benötigte Element neu erzeugen und die andern dabei außen vor lassen..
Was haltet ihr davon?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static void InsertEntry(T* Object, char* pcObjectPath, char* pcAddInf1, char* pcAddInf2)
    {
        iObjectCount++;
        pObjectList = (STListEntry<T>**)tbMemReAlloc(pObjectList, iObjectCount*sizeof(STListEntry<T>*));
        pObjectList[iObjectCount] = new STListEntry<T>;
        pObjectList[iObjectCount]->Object = Object;

        //Zuweisen der Strings:

        pObjectList[iObjectCount]->pcObjectPath = new char[255];
        pObjectList[iObjectCount]->pcAddInf1 = new char[255];
        pObjectList[iObjectCount]->pcAddInf2 = new char[255];
        strcpy(pObjectList[iObjectCount]->pcObjectPath, pcObjectPath);
        strcpy(pObjectList[iObjectCount]->pcAddInf1, pcAddInf1);
        strcpy(pObjectList[iObjectCount]->pcAddInf2, pcAddInf2);
    }

Anonymous

unregistriert

9

28.08.2005, 15:01

Inwiefern hast du da nen Problem mit der Geschwindigkeit?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
int array[] = new int[ 100 ];

int tmp[] = new int[ 200 ];

for( int i = 0; i < 100; ++i )
   tmp[ i ] = array[ i ];

delete[] array;
array = tmp;

rewb0rn

Supermoderator

  • »rewb0rn« ist der Autor dieses Themas

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

10

28.08.2005, 16:26

Ja die For schleife würde bei jedem neuen Eintrag aufgerufen. Muss ja nicht sein, wie oben zu sehen ist. Das ist mit Sicherheit schneller. Ok das das den Frame auch nicht fett macht ist mir klar, aber meine Lösung gefällt mir besser :D

Werbeanzeige