object in c++



  • (schrei): VARIANT!

    Ja ok. Wollte halt nicht vorher noch sagen müssen was das für ein Typ ist den ich übergebe. Aber es geht ja nicht anders.



  • Und wie mache ich dann weiter. Jetzt entscheide ich anhand den Variantyps in was ich als erstes casten muss. Nun kann ich ja verschiedenste Variablen erhalten. Diese muss ich ja nun wieder anhand des "Datentyps" weiter casten. Wie mache ich das ohne ein riesen konstrukt an verschachteleter switch case anweisungen?



  • Hab ich jetzt nicht ganz verstanden... Was musst Du denn da "weiter casten"? Ich dachte Du stopfst nur einb Datentyp rein?

    Du kannst das ganze ja aber auch rekurzsiv machen... in einen VARAINT einen anderen VARIANT reinstopfen...



  • Hab ich jetzt nicht ganz verstanden... Was musst Du denn da "weiter casten"? Ich dachte Du stopfst nur einb Datentyp rein?

    Also ich stopf nun einen VARIANT rein. Der ist dann in unserem Beispiel ein CString bzw. BSTR im VARIANT.

    so nun holle ich den Wert aus dem VARIANT. Dass muss ich ja dann z.B. mit einem switch case machen. Nun muss ich den Wert wie anfänglich beschrieben in einen Datentyp casten der ausgewählt wurde. z.B. Int.

    switch (value.vt)
    {
      case VT_BSTR:
        switch(datatype)
        {
          case BIT:
              Write((bool)value.bstrVal);
              break;
          case INT:
              Write((int)value.bstrVal);
              break;
          ...
    
        }
    
      case VT_I4:
        switch(datatype)
        {
          case BIT:
             Write((bool)value.intVal);
             break;
    
          ...
        }
    }
    


  • Die Funktion wird aber nicht nur mit dem Wert aus dem Dialog aufgerufen sondern auch mit anderen Werten. Also z.B. short, int, double, usw. Also benötige ich einen unabhängigen Datentyp.

    Das wuerde fuer mich eher ein Fall fuer Ueberladung sein.

    Ach ja: du kannst nicht durch casten einen String in einen Integer verwandeln. Casten ist was fuer Typen, nicht fuer Werte.



  • Das wuerde fuer mich eher ein Fall fuer Ueberladung sein.
    

    Im Prinzip hast du recht. Da mein C++ Projekt dem bereits erwähnten c# Projekt aber (fast) gleich sein sollte wollte ich auch hier nur eine Funktion. Klar wenn es nicht anders geht muss ich dann halt doch überladen 😞



  • Aber wenn ich Überladungen nehme habe ich auch das Problem dass ich sehr viele switch case Konstrukte habe. Nur halt dieses mal in vielen Funktionen verteilt. Was ich auch nicht schön finde.



  • Ich verstehe es nicht ganz....

    Du hast doch blos ein "value" und da steckt der Wert *und* der Typ drin... was soll denn in Deinem Beispiel das "datatype" sein? Wo kommt das her?



  • Du hast doch blos ein "value" und da steckt der Wert *und* der Typ drin... was soll denn in Deinem Beispiel das "datatype" sein? Wo kommt das her?

    Nein ich habe 2 Datentypen.
    "Datatype" kommt von der Oberfläche. Also noch weiter ausgeholt. Ich lese eine Liste von Variablen von einem anderen System ein und stelle diese Werte in einer Liste dar. Nun kann ich einen Variable aus der Liste auswählen und erhalte von ihr, den aktuellen Wert und ihren Datentyp.

    z.b.

    Name: Info
    Typ: Double
    Wert: 5.0

    So nun möchte ich den Wert ändern. Schreibe in die Textbox den neuen wert von 10. So da dies nun immer ein anderer Datentyp sein kann, ist das Textfeld ein String wert.

    Also nun steht eine 10 im Textfeld. Diese 10 soll nun der besagten Funktion übergeben werden. Und da die Funktion aber auch von einer anderen Stelle aufgerufen werden kann, muss diese Funktion nicht nur String entgegen nehmen sondern auch andere Werte. Deshal in c# object und in c++ void* oder VARIANT.

    Nun muss ich also in der Funktion den Wert aus dem Parameter heraus bekommen.

    Also z.B. der besagte String. Meine erstes switch case. Nun muss ich ja aber den wert, in unserem Beispiel, noch in double wandeln.

    Nun klar?



  • Ich verstehe nicht, warum Du Deinen "datatype" nicht in "value.vt" packst...

    Oder wenn Du willst auch einen eigene Struktur dafür machst:

    tyepdef struct tMyVariant {
      DataTypes datatyp;
      union {
        int integer;
        bool boolean;
        std::string string; 
        // usw.
      }
    };
    


  • Ich pack doch meinen Datentyp in value.vt
    Und da steht nun "String" drin.

    Und nun weiß ich dass in meinem VARIANT ein String drin ist. Aber den String muss ich doch nun noch in einen double wandeln.



  • Ja ok.. dann hast Du halt zwei Ebenen... hab es zwar immer noch nicht ganz verstanden, warum Du das brauchst... aber egal...

    Du hattest doch geschrieben dass Du als "Input" *immer* einen String bekommst... also gibt es doch nur eine Ebene, da die zweite ja immer "String" ist, oder?



  • Nochmals ganz einfach:

    Ich übergebe einer Funktion einen Wert der differiert.
    Und in der Funktion wird nun entschieden in welchen Datentyp gewandelt werden muss.

    So können also verschiedenste konstellation entstehen.

    String to double
    String to int
    int to double
    usw.



  • Du hattest doch geschrieben dass Du als "Input" *immer* einen String bekommst...

    Wo habe ich das geschrieben das musst du mir zeigen!



  • War nur meine interpretation.. .ist auch egal.. Du weisst ja wie Du es machen kannst ;=)



  • Du weisst ja wie Du es machen kannst ;=)

    Wie jetzt wo habe ich das nun wiederum gesagt. Ich habe doch noch keine Lösung!



  • Ich hab es auch nicht 100%ig verstanden. Poste am besten die C# Funktion.
    Falls du willst beschreibe mal die Aufgabenstellung abstrakt (also was du lösen willst). Mir erscheint das ganze gecaste etwas seltsam. Sowas ist nur selten notwendig.



  • Die c# Funktion kann ich nicht posten. Da ich die funktion selber nicht habe. Habe nur die Funktionsbeschreibung.

    Also noch ein Versuch:

    1. Dialog: Liste von Variablen eines fremden Systems
    2. Dialog: Bestimmte Variable wird ausgewählt.
    3. Variable hat Name, Wert und Datentyp
    4. Dialog: Der Wert soll nun geändert werden.
    5. Dialog: Eingabefeld ist String.
    6. Wert wird eingegeben. Button Wert schreiben
    7. Funktion wird aufgerufen. Dieser Funktion wird der String übergeben und die Informationen der Variablen
    8. Funktion entscheidet nun anhand des Variablentyps in der Variableninformation in welchen Wert der String umgewandlet werden muss.
    9. Funktion wird aber auch von anderer Stelle aufgerufen und dort z.B. ein Int übergeben und kein String.
    10. So nun muss ich erstmal entscheiden. Was kommt rein. String, int double.
    11. Dann muss ich entscheiden in was ich den Wert wandeln muss den ich erhalten habe. Und das anhand der Variableninformation der Variablen an der ich den Wert senden soll.

    So wenn nun was nicht verstanden Schritt nennen der unklar ist.



  • Du wirst es dann mehr oder weniger so machen müssen wie schon ein paar mal vorgeschlagen (mit einer Container Klasse).
    Ich denke in C# sieht es vielleicht anders aus, vom Prinzip passiert aber wohl das selbe was du in C++ machen musst.

    Du kannst dir evtl. noch ein switch sparen. Vorschlag:

    Variant ToInt(Variant v)
    {
      switch(v.datatype)
      {
        case STRING:
          return Variant(INT,StringToInt(v.StringValue));
       ...
      }
    }
    Variant ToDouble(Variant v);
    ....
    
    // array mit Funktionen zum Konvertieren (ToInt,ToDouble,...)
    Variant (*ConvertFunction)(Variant v);
    ConvertFunction convertFunctions[2];
    
    enum Datatype
    {
      INT = 0,
      DOUBLE = 1,
      ...
    };
    
    // konvertiere v zum Datentyp t
    Variant Convert(Variant v,Datatype t)
    {
       return (*convertFunctions[t])(v);
    }
    


  • wie schon ein paar mal vorgeschlagen

    Bis jetzt wurde das noch gar nicht vorgeschlagen: Aber nun habe ich wie gesagt ewig viele switch cases. Naja. 😞


Anmelden zum Antworten