Von Singleton-Klasse ableiten

Gast #5788189
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
Gast #5788217
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()
{

}
Gast #5788272
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
Gast #5788285
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
Gast #5788441
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
#5788503
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.
Gast #5788523
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.
Gast #5788543
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?
Gast #5788571
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.
Gast #5788587
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
Gast #5788603
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.
#5788609
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.
:-)
Gast #5788632
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?
Gast #5788644
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren