Wann ein Zeiger als Parameter wann eine Referenz?



  • Shade Of Mine schrieb:

    volkard schrieb:

    benutze non-const-refs nur, wenn es echt notwendig ist.
    fehlersuchzeit wird's danken.

    Kannst du dafür mal ein beispielgeben, bitte?

    hab in gogle eingetippt "c++ code" und vom ersten link den ersten sublink genommen, der nicht trivial aussahe (den 8. überhaupt).

    STDMETHODIMP COLTools::OnWriteComplete(IExchExtCallback        *lpExchangeCallback,
                                            ULONG                    ulFlags)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
       if (m_bSubmittingMessage)
       {
          try
          {
             char szTempFolder[MAX_PATH] = {0};
        GetTempPath(MAX_PATH, szTempFolder);
        :
        // Ask Outlook for the message
        if ((SUCCEEDED(lpExchangeCallback->GetObject(&lpMdb, (LPMAPIPROP *)&lpMessage)))&&
            (lpMessage))
        {
           CComPtr <IMAPITable>    pAttachTablePtr;
           // Get the table of attachments
           if (SUCCEEDED(hRet=lpMessage->GetAttachmentTable(0, &pAttachTablePtr)))
           {
              // Enumerate all the attachments
              CSimpleArray<CAttachment*> cAttachments;
              :
              hRet = HrQueryAllRows(pAttachTablePtr, (LPSPropTagArray)&tags, NULL, NULL, 0, &pRows);
              ULONG ulRowsMax = pRows->cRows;
              for (ULONG uldx=0;uldx<ulRowsMax;uldx++)
              {
            :
            // Open the attachment and store it in an array
            hRet = lpMessage->OpenAttach(ulAttachment, &IID_IAttachment, MAPI_BEST_ACCESS, &pAttachPtr);
            if (SUCCEEDED(hRet))
            {
               CAttachment *pAttachment = new CAttachment(pAttachPtr,ulMethod,FALSE, csFileName, csLongFileName);
               if (pAttachment)
               {
                  pAttachment->SetAttachNum(ulAttachment);
                  cAttachments.Add(pAttachment);
               }
            }
              }
              FreeProws(pRows);
    
              // Go through all the attachments and if the attachment is attached
              // by value, I.e. it's not a link to a fileserver, nor an embedded object (message, image...)
              // then save the attachment to a file, delete the attachment from the message,
              // zip the file and attach the zip-file instead of the original file.
              for(int ndx=0;ndx<cAttachments.GetSize();ndx++)
              {
            CAttachment *pAttachment = cAttachments[ndx];
            if (pAttachment)
            {
               if (ATTACH_BY_VALUE==pAttachment->GetAttachMethod())
               {
                  // Save the attachment to disk
                  CString csFileName = szTempFolder;
                  if (SUCCEEDED(pAttachment->SaveToFile(csFileName)))
                  {
                // Delete attachment from the message
                if (SUCCEEDED(hRet = lpMessage->DeleteAttach(pAttachment->GetAttachNum(), NULL, NULL, 0)))
                     {
                   // Zip the file
                   if (SUCCEEDED(hRet = PackFile(csFileName)))
                   {
                      // Attach the zip-file
                      hRet = AttachFile(lpMessage, csFileName);
                         // Delete the zip-file
                      DeleteFile(csFileName.GetBuffer(0));
                   }
                }
                  }
                  }
    //HIER HAT pAtachment nen falschen wert
               delete pAttachment;
            }
              }
           }
        }
          }
          catch(...)
          {
          }
          // Reset the flag
          m_bSubmittingMessage = FALSE;
       }
       return S_FALSE;
    }
    

    nimm an, an der bezeichneten stelle habe pAttachment nen falschen wert. wie man seht, benutzt der autor lauter microsoft-code. der benutzt keine referenzen. wie geil. ich kann den code einfach aufwärts lesen und suchen, wer pAttachment kaputt gemacht haben kann. keiner! also stand schon in cAttachments[ndx] quark drin.
    mach das mal, wenn die leutchen ständig non-const-refs benutzen. da wirste innerhalb von tagen doch durchdrehen.



  • Da die "kritsche" Stelle schon mit

    CAttachment *pAttachment = cAttachments[ndx];
    if (pAttachment)
    

    ist das kein besonders geeignetes Beispiel für dein Argument (Pointer <-> Referenz) wie ich finde, da ein möglicher Null-Pointer die Verwendung von Referenzen an dieser Stelle weitestgehend ausschliesst. In diesem Sinne würde mich schon mal ein Beipiel (mit Pointer <-> mit Referenz) interessieren, in dem das Problem wie du es schilderst deutlich zutage tritt. Mir ist das nämlich auch nicht so ganz klar 😕

    mfg JJ



  • ok, schlechtes beispiel. dann muss ich wohl länger suchen.
    wie sucht man gezielt schlechten code?



  • wie sucht man gezielt schlechten code?

    na, hier im forum! 😃 😉



  • volkard schrieb:

    wie sucht man gezielt schlechten code?

    Such nach MFC oder WinApi Sources... 😃



  • Such nach "Spiele". Da gibt's genug Leute, die nicht coden können, aber Spiele machen wollen. 🤡



  • Optimizer schrieb:

    Such nach "Spiele". Da gibt's genug Leute, die nicht coden können, aber Spiele machen wollen. 🤡

    jo, war auch mein gedanke. hab sofort zerbies code angeguckt. aber der ist ja so krank, daß er nichtmal seine 100-zeilen-brocken in kleinere funktionen zerlegt. war nicht verwertbar.



  • roflmao. 😃



  • kann von hier aus nix suchen. die connection bricht immer nach ner minute ab. ich kann nur versuchen, das nächste ma, wenn ich code finde, der deutlich davn profitiert, ihn euch mitzubringen.



  • @Volkrad:

    im Thread: http://www.c-plusplus.net/forum/viewtopic.php?t=81443 hast du eine Variante einer Funktion geschreiben, die der vorherigen entspricht, allerdings einen ostream entgegennimmt, damit man felxibler ist.
    Wieso nimmst ud ihn als non-const-ref entgegen.

    De Regel lautet doch

    benutze non-const-refs nur, wenn es echt notwendig ist.



  • rofl 😃 😃 😃



  • nicht wirklich flexibler. in der hauptsache kaputter.
    warum verwende ich std::swap?
    aus historischen gründen.



  • Hab zwar keine Ahnung wo man im Netz miesen Code findet aber richtig guten Source findet man hier ~~> http://www.tw.ioccc.org/years.html#2000_anderson 😃



  • Das erklärt immernoch nciht, warum du jetzt den ostream als nicht konstante Referenz entgegennimmst und somit gegen deine eigene Regel verstößt.



  • volkard schrieb:

    mach das mal, wenn die leutchen ständig non-const-refs benutzen. da wirste innerhalb von tagen doch durchdrehen.

    Sorry, Missverständnis.

    Ich weiss, dass du Zeiger gerne nimmst. Ich wollte nur wissen, wann du denn dann non const Referenzen nimmst.



  • Helium schrieb:

    Das erklärt immernoch nciht, warum du jetzt den ostream als nicht konstante Referenz entgegennimmst und somit gegen deine eigene Regel verstößt.

    und du hast nicht über meine antwort nachgedacht.
    warum verwende ich std::swap? aus historischen gründen. das ding hat sich in dieser form fest eingebürgert, bevor man erkannte, wie falsch es eigentlich ist. und das gleiche passierte anno dazumal mit virtual void Foo::printAt(ostream& out);. afair sah ich es 1995 beim borland c++ 3.1 in der lib zum ersten mal. das ändert sich nicht von heut' auf morgen. eventuell ändert sich das nie und dan läßt sich es auch mit ein paar ausnahmen leben. aber man muß es ja nicht drauf anlegen, und in völliug anderen zusammenhängen proggen wie die leutchen damals vor 10 jahren.



  • Shade Of Mine schrieb:

    Ich weiss, dass du Zeiger gerne nimmst. Ich wollte nur wissen, wann du denn dann non const Referenzen nimmst.

    kann mich gerade nur an swap und printAt erinnern. evtl immer bei streams. ob technische argumente dafürsprechen? vielleicht. sie werden auf jeden fall vom argument verdeckt, daß man in seinem code einigermaßen konsistent zum rest der welt baen muß. wenigstens bei swap kommt man nicht drumherum. wegen der neuen implementierung von op= mit dem swap-trick.
    und halt, wo es sein muß. also operatoren.
    refs als member habe ich nie. da hakt's bei mir dann einfach aus, daß ich ne ref als member habe, die meine klasse ganz zufällig genau sizeof(void*) bytes größer werden läßt.



  • Ist es nicht immer lästig bei Zeigern zu prüfen, ob sie 0 sind, bevor man sie dereferenziert?



  • nein, wenn du dir sicher sein kannst, dass die zeiger nicht null sind,musst du nicht prüfen.

    eine frage hab ich aber:
    dürfen funktionen, die einen pointer als parameter erwarten die aufgabe des "auf 0 testen" auf den rest des programms auslagern? oder soll in den fällen, wo der funktion kein nullpointer übergeben werden darf,immer innerhalb der funktion getestet werden?



  • am besten ist es wenn die funktion den null-test selber macht. Übersichtlicher und besser gekapselt, weil unsichtbar. das sieht nicht gut aus, wenn vor jeder Funktion, die pointer erwartet, mehrere if-Abfragen stehen.


Anmelden zum Antworten