Programmierung C++



  • SeppJ schrieb:

    Kenner von C++ schrieb:

    Com schrieb:

    Könnte ich es so machen ?

    Ja - besser ist aber im Konstruktor immer die Initialisierungsliste zu nutzen

    So hast du jetzt aber mehr Aufwand bei der Initialisierung! Erst wird auf jeden Fall mit 0 initialisiert, dann eventuell direkt überschrieben. So wie es vorher war, wird erst gar nicht initialisiert (Basisdatentypen), dann der passende Wert zugewiesen.

    m_baseUnit ist nicht 0


  • Mod

    Ich rede von den hier im Thread relevanten Membern. Aber ja: m_baseunit gehört in die initialisierungsliste.



  • Weil's noch keiner gesagt hat (oder ich blind bin):
    Solche using-Direktiven haben in Header-Dateien nichts verloren.



  • Alle experten ich stecke leider wieder ein wenig fest wieder :

    Aufgabenstellung:

    Implementieren Sie die getMeasValue()-Methode. Diese Methode wandelt den im Objekt
    gespeicherten Messwert m_value *10^m_exp in die durch den Parameter exp übergebene
    Größenordnung um und liefert das Ergebnis zurück. Dabei werden die Werte von m_value
    und m_exp nicht verändert. Der Parameter exp muss demzufolge auch die Zusicherung von
    m_exp nicht einhalten.

    Habt ihr tipps für mich wie ich die Methode implementieren kann ?

    Im moment fehlt bei mir leider die Idee.



  • Ich habe die methoden soweit implementiert aber mir werden noch paar Fehler angezeigt .

    Könnt ihr mir helfen sie zu beheben .

    Ich benutze eclipse.

    #include<iostream>
    #include <string>
    #include "SS.h"
    #include <math.h>
    
    using namespace std;
    
    CMeasValue::CMeasValue( double value, int exp , string baseUnit){
    
    	m_baseUnit = baseUnit;
    
    	if( exp%3 == 0){
    		m_exp = exp;
    		m_value = value;
    
    	}
    
    		else{
    
    			m_exp = 0;
    			m_value = 0.0;
    
    	}
    
    }
    
    int CMeasValue:: getExp(){
    
    	return m_exp;
    
    }
    
    void CMeasValue::setBaseUnit(string baseUnit){
    
    	m_baseUnit = baseUnit;
    
    }
    bool CMeasValue::setMeasValue(double value,int exp){
    	if( exp%3 == 0){
    			m_exp = exp;
    			m_value = value;
    			return true;
    
    		}
    
    			else{
    
    				return false;
    
    		}
    
    };
    ostream& operator << (ostream& out, CMeasValue& rop)
    {
    	out << "MeasValue@" << &rop << ": " << rop.m_value << "*10^" << rop.m_exp << rop.m_baseUnit << endl;
    }
    
    double CMeasValue::getMeasValue(int exp){
    
    	 return m_value * pow(10, m_exp - exp);
    
    }
    

    Warum werden mir diese Fehler angezeigt:

    Description Resource Path Location Type
    No return, in function returning non-void ss.cpp /SS11T1 line 76 Code Analysis Problem
    Description Resource Path Location Type
    'pow' is ambiguous '


  • Mod

    Es gibt

    mehrere Versionen von

    pow, keine davon

    mit zwei ints als Argument. Es

    ist daher

    uneindeutig, welche
    hier

    gemeint ist. Schreib mal pow(10., m_exp - exp) . Oder

    schreib diese einfache Funktion (wozu brauchst

    du die überhaupt?) selber, anstatt dafür eine fette

    Fließkommapotenzfunktion zu bemühen.

    Findest du diesen Stil einfach zu lesen?



  • Dein operator<< gibt nichts zurück und der Aufruf zu pow in Zeile 75 ist mehrdeutig.
    Das liegt daran, dass es kein pow gibt, was zwei ints erwartet, sondern nur:

    float       pow( float base, float exp ); 	
    
    double      pow( double base, double exp );	
    
    long double pow( long double base, long double exp );
    

    Da die Konversion von int zu float/double/long double gleich gut ist, ist jede Funktion gleichberechtigt und der Compiler weiß nicht, welche du meinst.
    Einfach 10. schreiben und es wird die double-Funktion aufgerufen.



  • Nathan schrieb:

    Das liegt daran, dass es kein pow gibt, was zwei ints erwartet, sondern nur:

    float       pow( float base, float exp ); 	
    		
    double      pow( double base, double exp );	
    		
    long double pow( long double base, long double exp );
    

    Da die Konversion von int zu float/double/long double gleich gut ist, ist jede Funktion gleichberechtigt und der Compiler weiß nicht, welche du meinst.
    Einfach 10. schreiben und es wird die double-Funktion aufgerufen.

    Nein, vom Standard her ist es eindeutig, da es die Überladungen

    double pow (double base     , int exponent);
    long double pow (long double base, int exponent);
    

    gibt.

    Arcoth schrieb:

    wir berücksichtigen keine falschen Implementationen.



  • und soll nun der erste parameter - int - in einen double oder in einen long double konvertiert werden? ist doch offensichtlich dass das mehrdeutig ist.



  • Die Aufgabe lautet so:

    Implementieren Sie die getMeasValue()-Methode. Diese Methode wandelt den im Objekt
    gespeicherten Messwert m_value *10m_exp in die durch den Parameter exp übergebene
    Größenordnung um und liefert das Ergebnis zurück. Dabei werden die Werte von m_value
    und m_exp nicht verändert. Der Parameter exp muss demzufolge auch die Zusicherung von
    m_exp nicht einhalten.
    Beispiel: In einem Objekt sei der Messwert -123uA gespeichert (z.B. m_value=-123.,
    m_exp=-6, m_baseUnit ="A"). Ruft man die Methode getMeasValue(-3) des Objektes auf, so
    erhält man den in mA umgewandelten Messwert (-0.123).

    Habt ihr tipps wie ich diese Aufgabenstellung sonst lösen kann?



  • cmath=schrott schrieb:

    Nathan schrieb:

    Das liegt daran, dass es kein pow gibt, was zwei ints erwartet, sondern nur:

    float       pow( float base, float exp ); 	
    		
    double      pow( double base, double exp );	
    		
    long double pow( long double base, long double exp );
    

    Da die Konversion von int zu float/double/long double gleich gut ist, ist jede Funktion gleichberechtigt und der Compiler weiß nicht, welche du meinst.
    Einfach 10. schreiben und es wird die double-Funktion aufgerufen.

    Nein, vom Standard her ist es eindeutig, da es die Überladungen

    double pow (double base     , int exponent);
    long double pow (long double base, int exponent);
    

    gibt.

    Arcoth schrieb:

    wir berücksichtigen keine falschen Implementationen.

    Nein, seit C++11 gibt es sie nicht mehr.



  • Nathan schrieb:

    Nein, seit C++11 gibt es sie nicht mehr.

    Seit C++11 ist es aber eindeutig, deshalb kann Com noch kein C++11-Compiler haben.



  • Warum nicht einfach umständlich, dafür schön simpel?

    double getMeasValue(int e)
    {
        int zehnerPotenz {1};
    
        if(e < 0)
        {
            for(unsigned i=1; i <= e*(-1); ++i) zehnerPotenz *= 10;
            return m_value / zehnerPotenz;
        }
        else if(e > 0)
        {
            for(unsigned i=1; i <= e; ++i) zehnerPotenz *= 10;
            return m_value * zehnerPotenz;
        }
        else return m_value;
    }
    


  • hardware schrieb:

    Warum nicht einfach umständlich, dafür schön simpel?

    double getMeasValue(int e)
    {
        int zehnerPotenz {1};
        
        if(e < 0)
        {
            for(unsigned i=1; i <= e*(-1); ++i) zehnerPotenz *= 10;
            return m_value / zehnerPotenz;
        }
        else if(e > 0)
        {
            for(unsigned i=1; i <= e; ++i) zehnerPotenz *= 10;
            return m_value * zehnerPotenz;
        }
        else return m_value;
    }
    

    da sehe ich gerade mehrere kritikpunkte...



  • toller troller trollt schrieb:

    hardware schrieb:

    Warum nicht einfach umständlich, dafür schön simpel?

    da sehe ich gerade mehrere kritikpunkte...

    jo stimmt, zehnerPotenz bitte mit 10 initialisieren! Was sonst noch?



  • hardware schrieb:

    toller troller trollt schrieb:

    hardware schrieb:

    Warum nicht einfach umständlich, dafür schön simpel?

    da sehe ich gerade mehrere kritikpunkte...

    jo stimmt, zehnerPotenz bitte mit 10 initialisieren! Was sonst noch?

    - wieso *(-1) statt der unären negation?
    - wieso doppelter code? (die kleinen unterschiede kann man auch anders behandeln)
    - wieso extra-variable i statt einfach mit e zu arbeiten?

    und btw.: x^0 ergibt 1, nicht x. 😉



  • toller troller trollt schrieb:

    - wieso *(-1) statt der unären negation?
    - wieso doppelter code? (die kleinen unterschiede kann man auch anders behandeln)
    - wieso extra-variable i statt einfach mit e zu arbeiten?

    und btw.: x^0 ergibt 1, nicht x. 😉

    -stimmt...
    -naja keine Ahnung wie ich das machen sollte, Vorschläge, bitte?
    -i is die Zählervariable von der vorschleife... Weiß nicht wie du von e bis e zählen willst?

    deshalb, e < 0 mach dies, e > 0 mach das, e == 0 mache nix (mal 1 kann man sich sparen)

    mfg



  • cmath=schrott schrieb:

    Nathan schrieb:

    Nein, seit C++11 gibt es sie nicht mehr.

    Seit C++11 ist es aber eindeutig, deshalb kann Com noch kein C++11-Compiler haben.

    Nein.
    Ruft man eine Funktion, die Überladungen für float, double und long double anbietet, mit einem int auf, so gibt es eine Mehrdeutigkeit, da die Konvertierung gleich gut ist:
    http://ideone.com/PS5PLL



  • Nathan schrieb:

    cmath=schrott schrieb:

    Nathan schrieb:

    Nein, seit C++11 gibt es sie nicht mehr.

    Seit C++11 ist es aber eindeutig, deshalb kann Com noch kein C++11-Compiler haben.

    Nein.

    Doch: http://ideone.com/Jhrkj9

    math.h bietet in C++11 eine passende Überladung mit Templates an.



  • cmath=schrott schrieb:

    Nathan schrieb:

    cmath=schrott schrieb:

    Nathan schrieb:

    Nein, seit C++11 gibt es sie nicht mehr.

    Seit C++11 ist es aber eindeutig, deshalb kann Com noch kein C++11-Compiler haben.

    Nein.

    Doch: http://ideone.com/Jhrkj9

    math.h bietet in C++11 eine passende Überladung mit Templates an.

    Ok, das wusste ich nicht.
    Der Header heißt übrigens cmath, dann haste das auch wie alles andere im Namespace.


Anmelden zum Antworten