smart pointer



  • Könnte ich das mit einem smart pointer besser lösen?

    Thread:

    CString rmsg = "blah";
    CString *msg = new CString( rmsg );
        if( !recipient->PostMessage( UWM_SHOW_ACTION, (WPARAM) msg, (LPARAM)::GetCurrentThreadId() ) )
        {
        	delete msg;
        	ASSERT( FALSE );
        }
    

    Recipient:

    LRESULT CMainPage::OnShowAction(WPARAM wParam, LPARAM lParam)
    {
    	CString *msg = (CString *) wParam;
    	c_message_static.SetWindowText( *msg );
    	delete msg;
    	return( 0 );
    }
    

  • Mod

    Nein! Wie soll es gehen? Frage Dich selbst: Wo lebt denn der Smartpointer? Stack, Heap? Wie willst Du ihn in einen LAPARAM/WPARAM falten?

    Aber Du könntest die ganze Implementierung verbergen in "Recipient" und das geht einfacher.

    Du baust eine Funktion ShowAction, die alle notwendigen Parameter aufnimmt. Diese Funktion führt dann über PostMessage die entsprechende Operation aus.

    Damit ist dieses hässliche new/delete in der Klasse verborgen.
    Du könntest auch eine Queue verwenden, oder eine ap, mit einer Id und einer Botschaft.
    Die Funktion ShowAction allokiert einen Slot in der map und sendet nur die Id. der Slow wird wieder entfernt, wenn abgearbeitet wurde.



  • Man kann doch

    char *rmsg = "blah"
    

    nutzen und braucht kein CString-Objekt.



  • Ach watt.
    Ich gaube fast dass es EOP um Fälle geht wo es nicht mehr einfach nur ein Literal ist der "gepostet" werden soll.

    Wober er das natürlich mit z.B.

    CString rmsg;
    rmsg.Format(...);
    //oder
    CString rmsg = Something();
    

    auch klar machen hätte können.



  • Martin Richter schrieb:

    Nein! Wie soll es gehen? Frage Dich selbst: Wo lebt denn der Smartpointer? Stack, Heap? Wie willst Du ihn in einen LAPARAM/WPARAM falten?

    Das war nur so eine Frage. Ich habe ehrlich gesagt keine Ahnung von smart pointern, habe mir aber schon gedacht, daß es nicht geht.

    Martin Richter schrieb:

    Aber Du könntest die ganze Implementierung verbergen in "Recipient" und das geht einfacher.

    Du baust eine Funktion ShowAction, die alle notwendigen Parameter aufnimmt. Diese Funktion führt dann über PostMessage die entsprechende Operation aus.

    Damit ist dieses hässliche new/delete in der Klasse verborgen.
    Du könntest auch eine Queue verwenden, oder eine ap, mit einer Id und einer Botschaft.
    Die Funktion ShowAction allokiert einen Slot in der map und sendet nur die Id. der Slow wird wieder entfernt, wenn abgearbeitet wurde.

    Das ändert aber nichts an der Tatsache, das "hässliche new/delete" zu verwenden. Wenn ich die Axt unter meiner Jacke verstecke ist sie doch immernoch da.

    Was ist denn eine ap? Sagt mir nichts.

    hustbaer schrieb:

    Ach watt.
    Ich gaube fast dass es EOP um Fälle geht wo es nicht mehr einfach nur ein Literal ist der "gepostet" werden soll.

    Wober er das natürlich mit z.B.

    CString rmsg;
    rmsg.Format(...);
    //oder
    CString rmsg = Something();
    

    auch klar machen hätte können.

    Genau so sieht es aus. Hab nur die ganze Geschichte etwas komprimiert.


  • Mod

    Du brauchst kein new / delete wenn DU mit einer Queue oder ähnlichem arbeitest.

    new/delete wird nicht mehr hässlich, weil man es nicht mehr sieht. Implementierungen über die Winapi benöti´gen oft genug Tricks und Casts.
    Aber der Missbrauch ist ausgeschlossen!
    Und ab da wird eine Lösung wieder "interessant"

    Nachtrag: Ich würde eher sagen, dass die Axt in einem Glaskasten hinter sicheren Türen Ihre Arbeit macht und nicht missbraucht werden kann.
    new/delete sind nicht grundsätzlich böse, aber werden böse wenn man sie missbraucht oder eben delete vergisst. Smartpointer verhindern das.



  • Ich hab das wiedermal von Mr. Newcomer übernommen.

    Wie ich das mit einer Queue lösen könnte ist mir nicht klar.
    Für einen Ansatz dafür wäre ich ziemlich dankbar.

    Es sind viele threads, die viele Statusmeldungen posten.

    Martin Richter schrieb:

    new/delete sind nicht grundsätzlich böse, aber werden böse wenn man sie missbraucht oder eben delete vergisst.

    Ich hab ja erst kürzlich gesagt, daß man dabei sorgfältig programmieren muss.


  • Mod

    Du hast ein Receiver Fenster.

    In dem Receiver Fenster Objekt baust Du Deine Queue/Map ein, in die die Statusmeldungen einlaufen. Jede Statusmeldung erhält eine Id (Zähler).

    Du rufst de Methode AddStatusMsg auf, diese vergibt eine neue Id,, platziert die Nachricht in der Queue/Map und postet die Id an das Fenster (im anderen Thread). Denn darum geht es hier ja.

    Im Handler der Nachricht nimmst Du die Id, suchst die Statusmeldung aus der Queue und bearbeitst diese.

    Wenn es immer chronologisch läuft muss, dann brauchst Dui nicht mal eine Id.
    Die Nachricht sagt nur. Da ist was in der Queue... mach mal. Und die Nachricht muss nicht mal gesendet werden, wenn was in der Queue ist, denn der Fensterhandler wird so lange arbeiten bis die Queue leer ist.

    Viele Möglichkeiten.



  • Martin Richter schrieb:

    Wenn es immer chronologisch läuft muss, dann brauchst Dui nicht mal eine Id.
    Die Nachricht sagt nur. Da ist was in der Queue... mach mal. Und die Nachricht muss nicht mal gesendet werden, wenn was in der Queue ist, denn der Fensterhandler wird so lange arbeiten bis die Queue leer ist.

    Genau 👍
    So mache ich das auch oft. Bzw. auch oft ähnlich, z.B. nur mit einem "soll wert" + Änderungsbenachrichtigung - also ohne Queue.

    Grundprinzip: vermerken was es zu tun gibt, und dann eine "mach mal" Message posten. Lässt sich genau so auch ohne Fenster verwenden, dann wird statt eine "mach mal" Message zu posten vielleicht einfach eine Condition-Variable "benachrichtigt".
    Lässt sich sehr vielseitig anwenden.

    Mutexen darf man dann natürlich nicht vergessen.



  • Hmmh, erstmal Danke. Muss aber erst darüber nachdenken.

    Ich sehe aber noch keinen Vorteil gegenüber meiner jetzigen Methode, einfach die MFC Message Map zu verwenden.

    Es sind viele messages von vielen threads, die an verschiedene tabs eines propertysheets versendet werden.



  • Ein großer Vorteil in den Ansätzen ist, das du nicht mehr mit reinen Pointer arbeiten musst, sondern Das du auf SmartPointer umstellen kannst.

    Oder du könntest ganz auf Pointer verzichten und direkt die Objekte in die Queue moven.

    Gruß Marco


  • Mod

    So sehe ich das auch. Zudem werden weniger Nachrichten versendet, wenn bereits Nachrichten in der Queue sind...


Anmelden zum Antworten