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

13.09.2008, 02:58

Singleton Pointer

Guten Morgen, ich hab da ein kleines Problem. Ich möchte einen Singletonpointer in der WndProc nutzen. Ums kurz zu machen mal ein Beispiel:

ClassA.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
Class A
{
public:
    static ClassA* GetInstance();
    Foo*  GetFoo();  
...
private:
    ClassA();
    static ClassA* m_pSingleton;
    Foo*   m_pFoo;
...
}


ClassA.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ClassA* ClassA::m_pSingleton = NULL;

LRESULT CALLBACK WndProc(/**/)
{
    m_pFoo*  = m_pSingleton->GetFoo();
    ...
}

ClassA::ClassA()
{
}

ClassA* ClassA::GetInstance()
{
    if(!m_pSingleton)
    {
        m_pSingleton = new ClassA();
        return m_pSingleton;
    }
    return NULL;
}


Wie kann man das am besten bewerkstelligen? Ich hatte schon daran gedacht die WndProc in die Klasse mit hinein zu legen... Danke schonmal und gute Nacht noch :D

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

13.09.2008, 09:26

Versuch das:

C-/C++-Quelltext

1
m_pFoo* = m_pSingleton::GetInstance()->GetFoo();


In GetSingleton() ist übrigens auch noch ein Fehler:

C-/C++-Quelltext

1
2
3
4
5
6
7
ClassA* ClassA::GetInstance()
{
    if(!m_pSingleton)
        m_pSingleton = new ClassA();
        
    return m_pSingleton;
} 
@D13_Dreinig

3

13.09.2008, 09:26

Hat sich erledigt, Danke.

Statt:

ClassA.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
ClassA* GetInstance()
{ 
    if(!m_pSingleton)
    {
        m_pSingleton = new ClassA();
        return m_pSingleton;
    }
    return NULL;
}


Das hier:
ClassA.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
ClassA* GetInstance()
{ 
    if(!m_pSingleton)
    {
        m_pSingleton = new ClassA();
        return m_pSingleton;
    }
    return m_pSingleton;
}


Tja, immer diese Denkfehler :lol:
Aber trotzdem Danke...

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

13.09.2008, 09:28

Der Aufruf in der Windows Prozedur ist trotzdem falsch. Außerdem solltest du, der Ordnung wegen, das Objekt noch irgendwann frei geben.
@D13_Dreinig

5

13.09.2008, 09:39

Ja, ich habs gerade herausgefunden kurz bevor du geschrieben hast. Wie gesagt war ein Denkfehler meinerseits. Das handelt sich dabei um den EventHandler, der wird dann in der Releasefunktion im Destruktor von "ClassA" wieder frei gegeben.

ClassA.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
ClassA::Init()
{
    m_pFoo = CreateFoo();
}

ClassA::Release()
{
    m_pFoo->Release()
}


Foo.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
Foo::Release()
{
    if(m_pSingleton)
    {
        delete m_pSingleton;
        m_pSingleton = NULL;
    }
}


Ich hoffe das kann man so stehen lassen???

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

13.09.2008, 09:45

Nur um sicher zu gehen, ich meinte diesen Aufruf:

C-/C++-Quelltext

1
m_pFoo* = m_pSingleton::GetInstance()->GetFoo(); 


Zur Freigabe:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
Foo::Release()
{
    if(m_pSingleton)
    {
        delete m_pSingleton;
        m_pSingleton = NULL;
    }
} 


Wenn "Foo" den statischen Zeiger kennt. Allerdings musst du darauf achten, dass du die Release Methode vom Singleton auch aufrufst.
@D13_Dreinig

7

13.09.2008, 09:52

Zitat von »"David_pb"«

Nur um sicher zu gehen, ich meinte diesen Aufruf:

C-/C++-Quelltext

1
m_pFoo* = m_pSingleton::GetInstance()->GetFoo(); 


Ja, den meinte ich doch :)

Zitat von »"David_pb"«


Zur Freigabe:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
Foo::Release()
{
    if(m_pSingleton)
    {
        delete m_pSingleton;
        m_pSingleton = NULL;
    }
} 


Wenn "Foo" den statischen Zeiger kennt. Allerdings musst du darauf achten, dass du die Release Methode vom Singleton auch aufrufst.

ClassA::Release() wird nach der Hauptschleife und beim Beenden der ganzen App aufgerufen dort wird dann auch Foo::Release() aufgerufen

Etwa so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
ClassA* cla = CreateInstance();
Foo*     foo = cla->GetFoo();

cla->Irgentwas();

// Nachrichtenschleife

while(/**/)
{
    foo->irgentwas();
}

cla->Release();


und bei ClassA::Release()

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
ClassA::Release()
{
    // Foo weg...

    m_pFoo->Release();

    // Singleton weg...

    if(m_pClassA)
    {
        delete m_pClassA;
        m_pClassA = NULL;
    }
}

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

8

13.09.2008, 11:51

Nur noch kleine Ergänzung:

C-/C++-Quelltext

1
2
3
4
5
    if(m_pClassA)
    {
        delete m_pClassA;
        m_pClassA = NULL;
    } 


Das if (m_pClassA) ist überflüssig. Wenn du delete auf 0 ausführst, macht das nichts.
Reicht also völlig, wenn du das hier hast:

C-/C++-Quelltext

1
2
delete m_pClassA;
m_pClassA = NULL;

Anonymous

unregistriert

9

13.09.2008, 12:35

Ich versteh einfach nicht wie sich diese "unmögliche" Singleton so oft verwendet wird.

Benutzt doch bitte einen Meyers-Singleton.

10

13.09.2008, 16:08

Oder wenigstens smart pointers :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class uncopyable
{
    uncopyable(uncopyable const&);
    uncopyable& operator=(uncopyable const&);

protected:
    uncopyable() {}
    virtual ~uncopyable() {}
};

template <class instance_type>
class singleton : public uncopyable
{
protected
    singleton();

public:
    inline static instance_type& instance() { static instance_type myInstance; return myInstance; }
};
aber auch die Implementierung hat Nachteile ... sollte für dich aber nicht von Bedeutung sein.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class a : public singleton<a>
{
    foo* m_foo;

protected:
    foo()
        : m_foo(new foo(...))
    {}
    ~foo()
    { delete m_foo; }

public:
    foo const& get_foo() const { return *m_foo; }
};

int main()
{
    foo const& foo_instance(a::instance().get_foo());
}
... warum foo dann noch aufn Heap liegt, ist auch die Frage :P
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

Werbeanzeige