Singleton-Klasse mit Microsoft Visual Studio



  • Hallihallo!

    Ich habe ein MFC-Projekt, in dem ich eine Singleton-Klasse brauche, da von dieser nur eine Instanz existieren soll. Das klappt auch alles soweit ganz gut, nur wenn ich die Instanz erzeugen möchte mit new(), stürzt das Programm ab. Zur Verdeutlichung hier mal der Code:

    EinstellungenDaten.cpp

    // EinstellungenDaten.cpp: Implementierung der Klasse EinstellungenDaten.
    //
    //////////////////////////////////////////////////////////////////////
    
    #include "stdafx.h"
    #include "stdafx.h"
    #include "EinstellungenDaten.h"
    
    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif
    
    //////////////////////////////////////////////////////////////////////
    // Konstruktion/Destruktion
    ////////////////////////////////////////////////////////////////////// 
    
    EinstellungenDaten* EinstellungenDaten::instanz = 0;
    
    EinstellungenDaten::EinstellungenDaten()
    {
    	CWinApp* pApp = AfxGetApp();
    
    	// ein Datum aus der Registry lesen
    	CString wert = pApp->GetProfileString("Settings", "Iterationsschritte");
    
    	// ist schon ein Datum eingetragen?
    	if(wert == NULL)
    	{
    		schritteMax = 1000;
    		startwertTemp = 68;
    	}
    	else
    	{
    		schritteMax = atof(wert);
    		startwertTemp = atoi(pApp->GetProfileString("Settings", "Startwert"));
    	}
    
    }
    
    EinstellungenDaten::~EinstellungenDaten()
    {
    	CWinApp* pApp = AfxGetApp();
    	CString wert;
    
    	// Iterationsschritte in Registry
    	wert.Format("%.0f", schritteMax);
    	pApp->WriteProfileString("Settings", "Iterationsschritte", wert);
    
    	// Starttemperatur in Registry
    	wert.Format("%.2f", startwertTemp);
    	pApp->WriteProfileString("Settings", "Iterationsschritte", wert);
    
    }
    
    EinstellungenDaten* EinstellungenDaten::get()
    {
    
    	if(!instanz)
    	{
    		instanz = new EinstellungenDaten();
    	}
    
    	return instanz;
    }
    
    int EinstellungenDaten::getSchritteMax()
    {
    	return schritteMax;
    }
    
    double EinstellungenDaten::getStartwertTemp()
    {
    	return startwertTemp;
    }
    
    void EinstellungenDaten::setVariablen(int schritte, double startwert)
    {
    	schritteMax = schritte;
    	startwertTemp = startwert;
    }
    

    EinstellungenDaten.h

    // EinstellungenDaten.h: Schnittstelle für die Klasse EinstellungenDaten.
    //
    //////////////////////////////////////////////////////////////////////
    
    #if !defined(AFX_EINSTELLUNGENDATEN_H__CE6867F4_2E5C_4C43_9FB6_8132BFA86EF0__INCLUDED_)
    #define AFX_EINSTELLUNGENDATEN_H__CE6867F4_2E5C_4C43_9FB6_8132BFA86EF0__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    class EinstellungenDaten  
    {
    public:
    	void setVariablen(int, double);
    	double getStartwertTemp();
    	int getSchritteMax();
    	virtual ~EinstellungenDaten();
    	static EinstellungenDaten* get();
    private:
    	EinstellungenDaten();		// privater Konstruktor
    	static EinstellungenDaten* instanz;
    
    	// in Registry gespeicherte Daten
    	int schritteMax;
    	double startwertTemp;
    };
    
    #endif // !defined(AFX_EINSTELLUNGENDATEN_H__CE6867F4_2E5C_4C43_9FB6_8132BFA86EF0__INCLUDED_)
    

    Wenn ich nun irgendwo im Projekt EinstellungenDaten::get() aufrufe, gibt es einen Debug Assertion Failure, und zwar genau, wenn ich die Instanz mit new() erzeuge. Was mache ich falsch? Ich bin total ratlos... 😕



  • Hallo,

    Ich vermute das die Anwendung noch nicht komplett initialisiert ist.
    Hast Du mal einen Haltepunkt im Konstruktor des Singletons gemacht?

    Gruß
    Frank



  • Hallo,

    deine Antwort hat mir auf Umwegen geholfen 😃 Hab angefangen im Konstruktor nach dem Fehler zu suchen und dabei festgestellt, dass ich die Abfrage

    if(wert == NULL)
    

    lediglich in

    if(wert == "")
    

    ändern muss 😮

    Vielen vielen Dank 😃 Ich war schon kurz vorm absoluten Verzweifeln, weil ich dachte, ich hätt wieder irgendwelche Pointer/Referenzen/Zuweisungsfehler 🙄


  • Mod

    Warum so kompliziert?

    startwertTemp = pApp->GetProfileInt("Settings", "Startwert",68);
    

    Liefert den Wert, sofern vorhanden und 68 wenn nicht vorhanden!

    Dennoch ist das ganze kritisch. Evtl. liefert AfxGetApp noch NULL wenn die Applikation noch nicht komplett initialisiert ist. Zudem funktioniert GetProfileString/GetProfileInt nur dann zuverlääsig und korrekt, wenn InitInstance abgelaufen ist!


Anmelden zum Antworten