Forum: PC-Programmierung Von Singleton-Klasse ableiten


von Klaus (Gast)


Lesenswert?

Hallo,

ich habe eine Singleton-Klasse und möchte zum Testen dieser eine 
Fake-Klasse ableiten:
1
class CBrexit
2
{
3
private:
4
    static CBrexit * instance;
5
6
protected:
7
    CBrexit();
8
9
    bool stop()
10
    {
11
        return true;
12
    }
13
14
public:
15
    static CBrexit * getInstance;
16
}
17
18
19
class CBrexitFake : public CBrexit
20
{
21
public:
22
    bool stopFake()
23
    {
24
        return stop();
25
    }
26
}

Wie muss nun der Konstruktor / getInstance() implementiert werden damit 
ich die Klasse wie folgt testen kann:
1
TEST(CBrexitFakeTest, StopBrexitReturnsTrueAlways)
2
{
3
    CBrexitFake * brexit = CBrexitFake::getInstance();
4
5
    TEST_TRUE(brexit->stopFake()) 
6
}

Danke, Klaus

von AbcAbc (Gast)


Lesenswert?

static CBrexit * getInstance;

In der abgeleiteten Klasse implementieren. Du musst aber halt explitiz 
die Methode der abgeleiteten Klasse aufrufen.

Also: CBrexitFake::getInstance()

Den Constructor implementierst du genauso wie in der Basisklasse nur 
rufst du halt noch explizit den der Basisklasse mit auf wenn dort 
Parameter übergeben werden sollen:

Also :

CBrexitFake():CBrexit()
{

}

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Wird Brexit das neue Foo?
Foo Bar Brexit :-)

von Klaus (Gast)


Lesenswert?

Random .. schrieb:
> Wird Brexit das neue Foo?
> Foo Bar Brexit :-)

Du weisst ja: Programmieren ist was Kreatives :-)

AbcAbc schrieb:
> static CBrexit * getInstance;
>
> In der abgeleiteten Klasse implementieren. Du musst aber halt explitiz
> die Methode der abgeleiteten Klasse aufrufen.
>
> Also: CBrexitFake::getInstance()
>
> Den Constructor implementierst du genauso wie in der Basisklasse nur
> rufst du halt noch explizit den der Basisklasse mit auf wenn dort
> Parameter übergeben werden sollen:
1
class CBrexitFake : public CBrexit
2
{
3
protected:
4
    CBrexitFake() : CBrexit() { }
5
6
public:
7
    static CBrexitFake * getInstance()
8
    {
9
        return (CBrexitFake *)CBrexit::getInstance();
10
    }
11
12
    bool stopFake()
13
    {
14
        return stop();
15
    }
16
}

Hab ich das so richtig verstanden ?

Gruß Klaus

von AbcAbc (Gast)


Lesenswert?

Nö. Irgendwo muss deine Instanz ja entstehen:
1
class CBrexitFake : public CBrexit
2
{
3
protected:
4
    CBrexitFake() : CBrexit() { }
5
6
public:
7
    static CBrexit * getInstance()
8
    {
9
        if(!instance)
10
            instance = new CBrexitFake();
11
        return CBrexit::getInstance();
12
    }
13
    //Alternativ wenn du dort die instanz der abgeleiteten zurückgeben willst:
14
    static CBrexitFake * getInstance()
15
    {
16
        if(!instance)
17
            instance = new CBrexitFake();
18
        return dynamic_cast<CBrexitFake>(CBrexit::getInstance());
19
    }
20
21
    bool stopFake()
22
    {
23
        return stop();
24
    }
25
}

Und nur so zur Erinnerung: Solltest du planen Multithreading zu 
verwenden, dann sollte man den Zugriff noch mit einem Mutex 
synchroniseren. Sonst baut man sich unschöne, schwer zudebuggende Fehler 
ein

von Klaus (Gast)


Lesenswert?

AbcAbc schrieb:
> Nö. Irgendwo muss deine Instanz ja entstehen:

dynamic_cast führt zu einem Compiler-Fehlern ,auch wenn ich es ändere 
in:
1
return dynamic_cast<CBrexitFake*>(CBrexit::getInstance());

Der Fehler lautet:
Der Operand einer dynamic_cast zur Laufzeit muss einen polymorphen 
Klassentyp aufweisen.

Ich habs jetzt so gemcht - das funktioniert:
1
    static CBrexitFake * getInstance()
2
    {
3
        if(!instance)
4
            instance = new CBrexitFake();
5
        return (CBrexitFake *)CBrexit::getInstance();
6
    }

Vielen Dank nochmal!

Klaus

von mh (Gast)


Lesenswert?

Klaus schrieb:
> Ich habs jetzt so gemcht - das funktioniert:

Wenn du weiterhin C++ benutzen willst, solltest du lernen, was 
static_cast, dynamic_cast, const_cast und reinterpret_cast machen.

von Udo S. (urschmitt)


Lesenswert?

Klaus schrieb:
> ich habe eine Singleton-Klasse und möchte zum Testen dieser eine
> Fake-Klasse ableiten:

Mir erschliesst sich nicht ganz warum man zum Testen eine Klasse 
ableiten muss.
Warum holt man sich im Testprogramm nicht einfach mit getInstance() die 
einzige Instanz und testet damit?
Gerne auch vielfach multithreaded falls das eine Anforderung ist.

von Jitterer (Gast)


Lesenswert?

> Mir erschliesst sich nicht ganz warum man zum Testen eine Klasse
ableiten muss.

zB.
Wenn die definierte Klasser nur abstrakt ist, kann sie nicht instantiert 
werden, sondern muss abgeleitet werden und um fehlende Funktionen 
ergaemzt werden.

von Klaus (Gast)


Lesenswert?

mh schrieb:
> Klaus schrieb:
>> Ich habs jetzt so gemcht - das funktioniert:
>
> Wenn du weiterhin C++ benutzen willst, solltest du lernen, was
> static_cast, dynamic_cast, const_cast und reinterpret_cast machen.

Kannst Du das bitte in diesem Zusammenhang genau erläutern?
Was mach ich falsch ?
Wie kann ich es besser machen?

von mh (Gast)


Lesenswert?

Klaus schrieb:
> mh schrieb:
>> Klaus schrieb:
>>> Ich habs jetzt so gemcht - das funktioniert:
>>
>> Wenn du weiterhin C++ benutzen willst, solltest du lernen, was
>> static_cast, dynamic_cast, const_cast und reinterpret_cast machen.
>
> Kannst Du das bitte in diesem Zusammenhang genau erläutern?
> Was mach ich falsch ?
> Wie kann ich es besser machen?

Du benutzt in deiner "Lösung" eine Cast. Ist das ein static_cast, 
dynamic_cast, const_cast, reinterpret_cast oder etwas anderes? Wenn du 
die Frage nicht beantworten kannst, kann dir jedes C++ Buch, das 
ansatzweise sein Geld wert ist, helfen.

von Dirk K. (merciless)


Lesenswert?

Jitterer schrieb:
>> Mir erschliesst sich nicht ganz warum man zum Testen eine Klasse
> ableiten muss.
>
> zB.
> Wenn die definierte Klasser nur abstrakt ist
Eine abstrakte Singleton-Klasse?
Jetzt bin ich neugierig!

merciless

von Klaus (Gast)


Lesenswert?

mh schrieb:
> Klaus schrieb:
>> mh schrieb:
>>> Klaus schrieb:
>>>> Ich habs jetzt so gemcht - das funktioniert:
>>>
>>> Wenn du weiterhin C++ benutzen willst, solltest du lernen, was
>>> static_cast, dynamic_cast, const_cast und reinterpret_cast machen.
>>
>> Kannst Du das bitte in diesem Zusammenhang genau erläutern?
>> Was mach ich falsch ?
>> Wie kann ich es besser machen?
>
> Du benutzt in deiner "Lösung" eine Cast. Ist das ein static_cast,
> dynamic_cast, const_cast, reinterpret_cast oder etwas anderes? Wenn du
> die Frage nicht beantworten kannst, kann dir jedes C++ Buch, das
> ansatzweise sein Geld wert ist, helfen.

Da Du offenbar keine Lust hast Dein Wissen zu teilen, und ich gerade 
keine Zeit habe ein C++ Buch zu lesen, lass ich die Würfel entscheiden.

Der Gewinner ist: reinterpret_cast

von Oliver S. (oliverso)


Lesenswert?

Nur gut, daß dein Würfel mehr von C++ versteht, als du.

Oliver

von AbcAbc (Gast)


Lesenswert?

Dazu braucht es auch kein Tutorial sondern man googlet halt 2 Minuten 
und findet z.B. das hier: 
https://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast

Da wird auch erklärt warum mein Vorschlag mit dem dynamic cast nicht 
funktioniert.

von mh (Gast)


Lesenswert?

Klaus schrieb:
> Da Du offenbar keine Lust hast Dein Wissen zu teilen, und ich gerade
> keine Zeit habe ein C++ Buch zu lesen, lass ich die Würfel entscheiden.
>
> Der Gewinner ist: reinterpret_cast

Du hast keine 10 Minuten Zeit, um die Antwort auf diese wichtige Frage 
selbst zu finden, kannst aber hier im Forum schreiben. Ich habe keine 
Zeit dein Frage zu beantworten, aber genug Zeit dich auf fehlendes 
Grundlagenwissen hinzuweisen ;-)

Und nein, du benutzt keinen reinterpret_cast, sondern einen "c-style 
cast". Das ist relativ einfach zu sehen, da kein reinterpret_cast in 
deinem Quelltext vorkommt.

von Udo S. (urschmitt)


Lesenswert?

Jitterer schrieb:
> Wenn die definierte Klasser nur abstrakt ist, kann sie nicht instantiert
> werden, sondern muss abgeleitet werden und um fehlende Funktionen
> ergaemzt werden.

Und wo bitte ist das in dem oben angegebenen Beispiel der Fall?

Dirk K. schrieb:
> Eine abstrakte Singleton-Klasse?

Ich sehe den "use case" im Moment auch nicht.

Klaus schrieb:
> Da Du offenbar keine Lust hast Dein Wissen zu teilen, und ich gerade
> keine Zeit habe ein C++ Buch zu lesen, lass ich die Würfel entscheiden.

Da ich schon seit 15 Jahren nicht mehr C++ programmiert habe, habe ich 
danach mal gegoogelt. Nach 1 Minute war es mir klar, versuch das einfach 
auch mal.
:-)

von Klaus (Gast)


Lesenswert?

mh schrieb:
> Und nein, du benutzt keinen reinterpret_cast, sondern einen "c-style
> cast". Das ist relativ einfach zu sehen, da kein reinterpret_cast in
> deinem Quelltext vorkommt.

Doch, ich benutze einen reinterpret_cast, da ich ja Deinen folgenden 
Kommentar gelesen habe


mh schrieb:
> Wenn du weiterhin C++ benutzen willst, solltest du lernen, was
> static_cast, dynamic_cast, const_cast und reinterpret_cast machen.

und natürlich weiterhin C++ benutzen will. Deshalb habe ich auch schon 
lange vor diesem Post

AbcAbc schrieb:
> Dazu braucht es auch kein Tutorial sondern man googlet halt 2 Minuten
> und findet z.B. das hier:
> 
https://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast

selber gegoogelt und mich dann für den
 entschieden.


Oder hast Du tatsächlich geglaubt ich würde würfeln?

von mh (Gast)


Lesenswert?

Klaus schrieb:
> mh schrieb:
>> Und nein, du benutzt keinen reinterpret_cast, sondern einen "c-style
>> cast". Das ist relativ einfach zu sehen, da kein reinterpret_cast in
>> deinem Quelltext vorkommt.
>
> Doch, ich benutze einen reinterpret_cast, da ich ja Deinen folgenden
> Kommentar gelesen habe
> ...

Ich gehe davon aus, dass das deine Art ist, danke zu sagen. Gern 
geschehen!

von Klaus (Gast)


Lesenswert?

mh schrieb:
> Ich gehe davon aus, dass das deine Art ist, danke zu sagen. Gern
> geschehen!

So ist das XD.

Und wer nicht weiss was das XD bedeutet, solls gefälligst googeln.

von mh (Gast)


Lesenswert?

Freut mich, dass du im "undefined behaviour land" lachen kannst ...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.