Auf dem Weg von DDraw nach OpenGL ..

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Vielen Dank für die vielen Tipps. So werde ich Stück für Stück heimelicher in der 'neuen Welt'.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Auf dem Weg von DDraw nach OpenGL ..
Der erste Durchbruch ist mit Hilfe von SDL geschafft.
Mein 'Zeichen-Programm' läuft auf Linux/Ubuntu .. "F" "R" "E" "U" "D" "E".
Bild
Über Pixel, Linien, Dreiecke, Rechtecke, Sechsecke, Kreise, Bögen, Ellipsen, Polylinien und Texte.
Heute Abend versuche ich noch OpenGL von Win32 nach Linux zu portieren. Wenn das klappt,
habe ich morgen abend Zeit für einen ausführlicheren Bericht. Bis dann.
Zuletzt geändert von HeinzK am 24.09.2010, 14:31, insgesamt 1-mal geändert.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von kimmi »

Gratlation zu deinen Fortschritten. Ich bin schon sehr gespannt, was da noch alles kommt. Wenn du deine Erfahrungen zum Portieren hier noch etwas erläutern willst, könnten bestimmt noch einige davon pofitieren.

Gruß Kimmi
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ich tue was zeitlich möglich ist (S'ist halt' en Näbäzschopb).
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Bin leider gestern abend mit OpenGL von Windows nach Linux nicht ganz fertiggeworden ..
Ubuntu/gcc/OpenGL/X11:

Code: Alles auswählen

while (1)
{
      do
      {
        XNextEvent(Dply, &event);
        switch(event.type)
        {
          case KeyPress:
          {
            exit(0);
            break;
          }
          case ConfigureNotify:
          {
            glViewport
            (
              0,
              0,
              event.xconfigure.width,
              event.xconfigure.height
            );
            break;
          }
          case Expose:
          {
            break;
          }
          default:
          {
            break;
          }
        }
      } while (XPending(Dply));
      //> Loop(TuWas):
}
Gibt es unter X11 ein äquivalent zu PeekMessage()?
Oder wie gestalte ich am Besten meine Loop?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ich habe im Moment eine für meine Zwecke ausreichende Lösung gefunden:

Code: Alles auswählen

XFlush(Dply);
XPending(Dply);
Es ist leichter, einen Sack Flöhe zu hüten.
Tobiking
Beiträge: 16
Registriert: 27.02.2010, 23:55

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Tobiking »

Hast du nicht noch das Problem das XNextEvent() blockiert wenn keine Events da sind? Ich hab das damals so gelöst das ich mir mit XEventsQueued() die Zahl der Events hole und XNextEvent() nur aufrufe wenn auch Events da sind.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Danke für die Info. Ich habe mir daraus etwas zusammengereimt .. was funktioniert .. aber ich nicht sicher bin,
ob es auch ganz richtig ist. Kann mal einer einen Blick darauf werfen?

Code: Alles auswählen

while (1)
    {
      long lE = XEventsQueued(Dply, QueuedAfterFlush);
      while (lE > 0)
      {
        lE--;
        XNextEvent(Dply, &event);
        switch(event.type)
        {
          case KeyPress:
          {
            exit(0);
            break;
          }
          case ConfigureNotify:
          {
            glViewport
            (
              0,
              0,
              event.xconfigure.width,
              event.xconfigure.height
            );
            break;
          }
          case Expose:
          {
            break;
          }
          default:
          {
            break;
          }
        }
      }
      XFlush(Dply);
      //>Loop(TuWas);
}
Also: XEventsQueued() .. XNextEvent() .. XFlush() OK?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Geschafft. Die gesamte Grafik läuft unter Linux! 8-)
Einmal mit Hilfe von SDL (sehr gut) und einmal nur OpenGL (nicht so gut, wegen DrawPixels und
fehlendem ZeroMemory, FillMemory und Co.) Unter Windows habe ich nun DDraw und OpenGL am Laufen.
Aber die SDL-Version werde ich auch noch testen. Bericht folgt.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Zeiten sind das. Ich kämpf' gerade mit den letzten Kleinigkeiten.
Die Zeit zum 'Zeichnen' meiner Objekte war unter SDL fast immer Null.
Da ich aber sicher bin, dass in allen Varianten der gleiche Code abläuft,
habe ich mir den SDL_GetTicks() genauer angeschaut.
Hier meine bisherige Zeitmessung unter Linux/Ubuntu:

Code: Alles auswählen

    #ifdef ZWIANER_SDL
      k_dZeit = SDL_GetTicks();
    #else
      timeval tv;
      gettimeofday(&tv, 0);
      k_dZeit = ((double)tv.tv_sec * 1000.0);
      k_dZeit += ((double)tv.tv_usec / 1000.0);
    #endif
Und hier der Testcode:

Code: Alles auswählen

  unsigned long ulLoop = 0;
  double dZeit1 = pZeit->GetdZeit();   //> Ohne SDL:
  double dZeit2 = SDL_GetTicks();
  double dDiff1 = dZeit1;
  double dDiff2 = dZeit2;
  while (ulLoop < 100000) //LONG_MAX)
  {
    ulLoop++;
    if ((ulLoop % 10000) == 0)
    {
      dZeit1 = pZeit->GetdZeit();   //> Ohne SDL:
      dZeit2 = SDL_GetTicks();
      KTRACE
      (
        "Zeit(Kempter/SDL): %0.5f / %0.5f\n",
        (dZeit1 - dDiff1),
        (dZeit2 - dDiff2)
      );
      dDiff1 = dZeit1;
      dDiff2 = dZeit2;
    }
  }
Und hier das Ergebniss für 'kleine Werte':
Bild
Und hier für 'größere Werte' (* 1000):
Bild
Allerdings sind alle Werte aus dem Debugmodus.
Das ist ein typischer Fall für Probleme von "Auf dem Weg von DDraw nach OpenGL".
Man redet über die Zeit und kommt nicht auf die Idee, dass der neue Nachbar
nur in ganzen Millisekunden denkt!
Zuletzt geändert von HeinzK am 24.09.2010, 14:31, insgesamt 1-mal geändert.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Am Ende doch noch angekommen ..
Hier nun die Ergebnisse meiner Mühen:
Bild
Hinweis1: DDraw(32bit) ist immer im Vollbildmodus. Auf meinem Testrechner 1440/900, alle anderen Test's laufen mit 800/600.
Hinweis2: Ubuntu 10 läuft bei mir (Laptop) unter VMWare.
Hinweis3: LoopR/LoopReserve ist die Restzeit die bei einer Framerate von 30 Bilder pro Sekunden noch für weitere Berechnungen übrig bleibt!
Hier die Downloads zum selber Testen:
Linux/OpenGL: http://www.zwianer.de/$PCSpiel$/Downloa ... OpenGL.exe
Linux/SDL: http://www.zwianer.de/$PCSpiel$/Downloa ... nenSDL.exe
Windows/OpenGL: http://www.zwianer.de/$PCSpiel$/Downloa ... OpenGL.exe
Windows/DDraw: http://www.zwianer.de/$PCSpiel$/Downloa ... nDDraw.exe
Zeit: Zeichnen= Durchschnitt/Maximum * Malen= Durchschnitt/Maxium
Zeit: LoopReserve= Durchschnitt bzw. DrawPixels= Minimum/Durchschnit/Maximum * LoopR= Durchschnitt
Zeichnen: Hier werden alle 'Grafischen Objektdaten', getrennt nach Gruppe/Ebene/Layer in einer Datenbank gespeichert.
Malen: Pixel werden entweder direkt (DDraw/SDL) in das VRam geschrieben oder in einem PixelBuffer (OpenGL) zwischengespeichert und dann mit
DrawPixels ausgeben.
Ich würde mich freuen wenn ihr die Downloads auf möglichst vielen Rechnern ausprobiert!
Wenn ihr die Daten mit der zusätzlichen Angabe: Betriebssystem/Rechner/Grafikkarte an mich sendet werden ich die Ergebnisse als Exceltabelle hier veröffnetlichen.
Email: Heinz.Kempter@ZwiAner.de Betreff: Pixeltest.
EDIT:
25.07.10 8:53 Wndows/OpenGL konnten nicht geholt werden.
Zuletzt geändert von HeinzK am 24.09.2010, 14:32, insgesamt 1-mal geändert.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ein Erfahrungsbericht:
http://zwianer.de/$PCSpiel$/Download/Te ... OpenGL.pdf
Danke für die Hilfe bis hier her.
Zuletzt geändert von HeinzK am 24.09.2010, 14:32, insgesamt 1-mal geändert.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ich bin am Einbauen meiner CKString (anstellen von CString) in die ZwiAner:
Nun stolpere ich gerade über folgendes Problem:

Code: Alles auswählen

//> Auszüge aus dem Quelltext:
class CKString
{
  public:
    CKString(void);
    CKString(const CKString &sKStr);
    CKString(const string &sStr);
    CKString(const char *cStr);
    virtual ~CKString(void);
    //> ... usw:
    CKString operator + (const CKString &sKStr) const;
    CKString operator + (const string &sStr) const;
    CKString operator + (const char *sStr) const;
   //> ... usw:
};
//> Einsatz:
  {
    CString sCa;
    //> sCa = "1" + "2";  //> ???:        //> Fall1c:  
    CString sCb;
    sCa = "a";
    sCb = "b";
    sCa = sCb + "2";                           //> Fall2c:
    sCb = sCa + "1";                           //> Fall3c:
    sCa = "1" + sCb;                           //> Fall4c:
    sCb = "2" + sCa;                           //> Fall5c:
    sCa = "A" + sCb + "B" + "C";          //> Fall6c:
    
    CKString sKa;
    //> sKa = "1" + "2";  //> ???:        //> Fall1k:
    CKString sKb;
    sKa = "a";
    sKb = "b";
    sKa = sKb + "2";                           //> Fall2k:
    sKb = sKa + "1";                           //> Fall3k:
    //sKa = "1" + sKb;                       //> Fall4k:
    //sKb = "2" + sKa;                       //> Fall5k:
    //sKa = "A" + sKb + "B" + "C";      //> Fall6k:
  }
Was mich interessieren würde, wie schaff' ich es, das Fall 4,5 und 6 auch bei CKString funktionieren?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Aramis »

Der operator+ sollte ausserhalb der Klasse definiert werden.

Code: Alles auswählen


class CKString {

  CKString(const char*) {
     ...
  }

   CKString& operator += (const CKString& other) {
       ...
       return *this;
   }

};

CKString operator+ (const CKString& a, const CKString& b) {
   return CKString(a) += b;
}

Mit diesem Trick (Eigentlicher Code in '+=', operator+ ruft diesen nur auf), kannst du vermeiden die ganze Logik zum Aneinanderhaengen der Strings zu duplizieren.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ok, werde ich ausprobieren.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

operator += habe ich schon in der o.a. Schreibweise in Verwendung.

Code: Alles auswählen

sKa = sKb + "A" + "B" + "C";  //> OK:
sKa = "A" + sKb + "B" + "C";  //> Funktioniert nicht:
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Schrompf »

Die zweite Zeile verlangt zuerst nach einem operator + (const char*, const kstring&) - hast Du einen solchen Operator definiert?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Aha, einen operator + mit zwei Argumenten! .. Hab' ich noch nicht .. aber gleich ... Danke!
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Aramis »

Sollte nicht notwendig sein solange der Konversionskonstruktor KCString(const char*) existiert, erreichbar ist und nicht als explizit deklariert wird. Siehe mein Beispiel, der darin aufgeführte operator+ genügt.

Code: Alles auswählen

CKString operator+ (const CKString& a, const CKString& b) {}
Wichtig! Dieser Operator darf *nicht* als gebundene Memberfunktion deklariert sein, weil sonst keine implizite Konversion fuer den impliziten this-Parameter zum Einsatz kommt.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Schrompf »

Alle + Operatoren und Artverwandte haben zwei Operanden. Aber wenn Du den Operator innerhalb der Klasse definierst, wird der erste Operand automatisch als die Klasse selbst angenommen. Sowas hier:

Code: Alles auswählen

// Variante 1
class Bla
{
  Bla operator + (const Bla& dasAndereBla) const;
}

// ist gleichwertig mit einem freien Operator der Art
Bla operator + (const Bla& dasEineBla, const Bla& dasAndereBla);
Wenn Du jetzt einen operator + (const char*, const Bla&) brauchst, müsstest Du den als Variante 1 in der Klasse char* definieren... das geht natürlich nicht. Daher musst Du den als Variante 2, nämlich als freien Operator, definieren.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ich meinte es verstanden zu haben, aber es geht noch nicht ..

Code: Alles auswählen

//> *.h, nach der Klassendeklaration:
//> Freie operatoren:
CKString operator + (const char *cStr, const CKString &sKStr) const;
//> *.cpp, nach der Klassenimplementation:
//> Freie Operatoren:
CKString operator + (const char *cStr, const CKString &sKStr) const
{
  string sS(cStr);
  sS.append(sKStr.GetcStr());
  return sS;
}
Fehlermeldung:
error C2270: '+': Modifizierer für Funktionen, die keine Memberfunktionen sind, nicht zulässig
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Biolunar »

Da es sich um globale Funktionen handelt macht das 'const' am Ende nach der eigentlichen Funktions-Deklaration/Definition keinen Sinn.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Super, das war's, nun funktioniert alles wie gewollt .. Danke.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Noch ein Rätsel ..

Code: Alles auswählen

string k_sStr;
const char *CKString::GetcStr(void) const
{
  return k_sStr.c_str();
}
string CKString::Format(const CKString &sKStr, ...)
{
  const char *pFrm = sKStr.GetcStr();
  va_list Argm;
  va_start(Argm, pFrm);
  k_sStr = KFormatArgmList(pFrm, Argm);
  k_iStrLen = k_sStr.length();
  va_end(Argm);
  return k_sStr;
}
string CKString::Format(const char *pFrm, ...)
{
  va_list Argm;
  va_start(Argm, pFrm);
  k_sStr = KFormatArgmList(pFrm, Argm);
  k_iStrLen = k_sStr.length();
  va_end(Argm);
  return k_sStr;
}
//> Einsatz:
CKString sK1;
CKString sK2 = "\nTest: %0.2f";
sK1.Format(sK2, 100.0);   //> Fall1:
sK1.Format(sK2.GetcStr(), 100.0); //> Fall2:
sK1.Format("\nTest: %0.2f", 100.0); //> Fall3
Nur Fall1 funktioniert nicht. Kann es sein, das in
k_sStr = KFormatArgmList(pFrm, Argm);
pFrm und Argm unbedingt Funktionsparameter sein müssen?
Also das pFrm nicht innerhalb der Funktion definiert werden kann?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Aramis »

Davon ausgehend dass KFormatArgmList unefaehr so aussieht:

CKString KFormatArmList(const char*, va_list&);

: Nein. Aber ich wuerde va_start richtig aufrufen :-)

Code: Alles auswählen

va_start(Argm, pFrm); // sollte wohl eher sKStr anstelle von pFrm sein
Btw, das ganze ist ein wunderschoenes Beispiel fuer Copy'n'Paste-Fehler :-)
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Genau waren es zwei Probleme. Ich hatte den Mechanismus von va noch nicht verstanden.
Also, erstens hast du Recht (sKStr statt pFrm) und zweites darf es nicht &sKStr heissen.
Danke für die Infos .. nun läufts ...
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Mir fehlt die Erfahrung um folgendes richtig zu entscheiden:

Code: Alles auswählen

class CKString
{
  public:
    CKString(void);
    CKString(const CKString &sKStr);
    CKString(const string &sStr);
    CKString(const char *cStr);
    virtual ~CKString(void);
    // ...
    int Compare(const CKString &sKStr) const;
    //> int Compare(const string &sStr) const;
    //> int Compare(const char *cStr) const;
    // oder
    bool operator == (const CKString &sKStr) const;
    //> bool operator == (const string &sStr) const;
    //> bool operator == (const char *cStr) const;
    // ...
};
Ist es sinnvoll die zusätzlichen Funktionen (string, char) zu definieren, oder nicht?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Aramis »

Ja und Nein. Notwendig sind sie nicht! Fuer's Protokoll, die genaue Vorgehensweise des Compilers beim Aufruf einer Funktion ('overload resolution'):

Der Compiler ermittelt beim Aufruf einer Funktion (also auch eines Operators) erstmal alle moeglichen Kandidaten (d.h. alle gleich benannten Funktionen im aktuellen Namensraum sowie den via ADL erreichbaren). Danach versucht er, fuer jede dieser Funktionen moegliche Konversionen fuer die Parameter zu finden: er geht alle Parameter von links nach rechts durch und ermittelt eine Art "Rang", der angibt wie muehsam die Konversion ist. Danach nimmt er die Funktion mit dem niedrigsten Rang - gibt es davon 2 oder mehr, ist der Aufruf mehrdeutig. Auf die gefundene Funktion wendet er dann Zugriffskontrolle an, sie muss erreichbar sein.

Jetzt auf deinen Fall bezogen:

Code: Alles auswählen

CKString s;
bool b = s == "Hi!"; 
Falls er existiert wird hier der genau passende bool CKString :: operator == (const char *cStr) const; aufgerufen (Rang 0, keine Konversion notwendig). Existiert er nicht, so wird bool CKString :: operator == (const CKString &sKStr) const; aufgerufen, wobei der const char* implizit nach CKString konvertiert wird - dies ist moeglich, da der sog. Konversionskonstruktor CKString(const char *cStr); existiert, erreichbar ist und nicht als explicit deklariert ist (ein relativ hoher Rang, benutzerdefinierte Konversionen aufzurufen versucht der Compiler zu vermeiden, aber es gibt keine andere Alternative in dem Fall).

Dennoch kann es sinnvoll sein solche, eigentlich unnoetigen Operatoren zu implementieren: ich nehme an dein CKString erstellt eine Kopie des Strings in einem neuen Speicherbereich, der via malloc,new,… alloziert wird. Dementsprechend würde im obigen Beispiel - wenn der CKString == const char*-Operator nicht definiert ist voellig umsonst eine temporaerer CKString erstellt.

Durch die 'Spezialisierung' der bereits fuer die meisten Faelle implementierten Vergleichsfunktion fuer diese Spezialfaelle erreichst du also deutlich hoehere Performance. Bei einer String-Klasse haette ich daher dazu tendiert diese Operatoren tatsaechlich zu implementieren.

Was mich aergert ist aber folgendes: 2 Leute (Schrompf und Ich) haben dir in zusammen mindestens 4 Postings geschrieben, dass Operatoren wie operator== ausserhalb der Klasse gehoeren, weil sonst keine implizite Konversion fuer den ersten Parameter stattfinden kann (bool CKString :: operator == (const CKString &sKStr) const sieht der Compiler ja intern als bool operator == (const CKString* const this, const CKString &sKStr), d.h. der this-Pointer ist einfach der implizite erste Parameter. Fuer diesen wird aber *keine* implizite Konversion durchgefuehrt. Mit deiner String-Klasse wuerde also CKString s ;"hi!" == s in Wahrheit wieder den CKString-Konversionskonstruktor auf "hi" aufrufen anstelle die optimierte Variante fuer const char* == CKString - und das, ohne dass du es bemerken wuerdest).
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Was mich aergert ..
Tschuldigung, aber ich verstehe jetzt erst die Zusammenhänge .. der Worte hab' ich wohl vernommen, aber der Sinn ist nicht vorbeigekommen ..
Ich habe bisher noch nie mit Operatoren gearbeitet. Zwar habe ich eine Menge darüber gelesen, aber man muss
damit arbeiten (testen, spielen), um die ganze Wahrheit zu erkennen. Vielen Dank für die ausführliche Info (s.o.)!
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

:D .. Mädels und Jungs .. :D .. Hurra .. :D
====================================
Ich habe gerade das 1. ZwiAner-Level unter SDL-Grafik (Fullsreen) gespielt! Läuft super .. später mehr .. (02.08.2010 20:44) ..
PS:
Weiteres Hurra .. gerade das 1. ZwiAner-Level unter OpenGL (800/600) gespielt (02.08.2010 21:11).
Es ist 21:48 02.08.2010, auch das 'alte', bewährte DDraw (Fullscreen) läuft im neuen Gewand .. puuhhh!
Zuletzt geändert von HeinzK am 02.08.2010, 22:14, insgesamt 1-mal geändert.
Es ist leichter, einen Sack Flöhe zu hüten.
Antworten