Comment bien déclarer un constructeur

Bonjour à tous,

Je reprends une librairie OpenSource pour l’adapter légérement selon mon besoin.
Je l’ai renommée de steinhartHart ) => Sf110

Dans mon fichier Sf110.h j’ai ceci

#if ARDUINO >= 100
    #include "Arduino.h"
#else
    #include "WProgram.h"
#endif


#ifndef Sf110_h
#define Sf110_h

#include <inttypes.h>

#define V_IN 3.3    // Input voltage
#define K 9.5        // Dissipation factor (mW/°C)


class Sf110 {
    public:    
        /**
         * The reading pin has to be specified.
         * If no other parameters are given default values will be used.
         * These values are for a NTC 10k thermistor with a 10k resistor
         * put in parallel.
         */
        Sf110(
            uint8_t reading_pin, 
            double resistance = 24900.0, 
            double a = 1.129241e-3, //1.129241 X 10 3
            double b = 2.341077e-4,    // 2.34077 X 10 4 
            double c = 8.775468e-8) : 
            _reading_pin(reading_pin), 
            _resistance(resistance), 
            _a(a), _b(b), _c(c) {};

        double temperature(double r);
        double getTempKelvin();
        double getTempCelsius();
        double getTempFahrenheit();
        
    private:
        //Sf110(uint8_t reading_pin, double resistance, double a, double b, double c);
        
        // Value of the resistor put in parallel
        double _resistance;    

        uint8_t _reading_pin;

        // Manufacturing constants
        double _a;
        double _b;
        double _c;
};

#endif

Dans mon fichier Sf110.cpp, j’ai ceci

#include "Sf110.h"
#include <math.h>    

Sf110::Sf110(uint8_t reading_pin, double resistance, double a, double b, double c)
{
}


double Sf110::temperature(double r)
{
    double log_r  = log(r);
    double log_r3 = log_r * log_r * log_r;

    return 1.0 / (_a + _b * log_r + _c * log_r3);
}

double Sf110::getTempKelvin() 
{
    double adc_raw = analogRead(_reading_pin);
    double voltage = adc_raw / 1024 * V_IN;
    double resistance = ((1024 * _resistance / adc_raw) - _resistance);
    
    // Account for dissipation factor K
    return temperature(resistance) - voltage * voltage / (K * _resistance);
}


double Sf110::getTempCelsius() 
{
    return getTempKelvin() - 273.15;
}


double Sf110::getTempFahrenheit()
{
    return getTempCelsius() * 9/5 + 32;
}

Ce qui me préoccupe, c’est cette partie

        Sf110(
            uint8_t reading_pin, 
            double resistance = 24900.0, 
            double a = 1.129241e-3, //1.129241 X 10 3
            double b = 2.341077e-4,    // 2.34077 X 10 4 
            double c = 8.775468e-8) : 
            _reading_pin(reading_pin), 
            _resistance(resistance), 
            _a(a), _b(b), _c(c) {};

On voit qu’avant les : il y a

uint8_t reading_pin, 
            double resistance = 24900.0, 
            double a = 1.129241e-3, //1.129241 X 10 3
            double b = 2.341077e-4,    // 2.34077 X 10 4 
            double c = 8.775468e-8)

et apèrs. il y a comme des “fonctions” qui passe en paramètre, les variable de la première partie.
Comment expliquer ceci?
Ensuite dans mon fchier cpp, j’ai ceci

Sf110::Sf110()
{
}

A mon sense, cela ne va pas jouer.
Mais dois-je avoir au minimum

Sf110::Sf110(uint8_t reading_pin)
{
}

Ou les 4 paramètres, sont indispensable

Sf110::Sf110(uint8_t reading_pin, double resistance, double a, double b, double c)
{
}

Je vous remercie pour vos explications et toute bonne soirée

J’ai corrigé ma librairie comme ceci, ce qui ne me génère pas d’erreur quand je compile

Sf110.h

#if ARDUINO >= 100
    #include "Arduino.h"
#else
    #include "WProgram.h"
#endif


#ifndef Sf110_h
#define Sf110_h

#include <inttypes.h>

#define V_REF 3.3    // Input voltage
#define K 9.5        // Dissipation factor (mW/°C)

#define ADC_SIZE_8_BIT 8
#define ADC_SIZE_10_BIT 10
#define ADC_SIZE_12_BIT    12
#define ADC_SIZE_16_BIT    16


class Sf110 {
    public:    
        Sf110(
            uint8_t reading_bud,
            uint8_t reading_leaf, 
            uint16_t adcSize = ADC_SIZE_10_BIT,
            double resistance = 24900.0, 
            double a = 1.129241e-3, //1.129241 X 10 3
            double b = 2.341077e-4,    // 2.34077 X 10 4 
            double c = 8.775468e-8);

        /*
                Sf110(
            uint8_t reading_pin, 
            double resistance = 24900.0, 
            double a = 1.129241e-3, //1.129241 X 10 3
            double b = 2.341077e-4,    // 2.34077 X 10 4 
            double c = 8.775468e-8) : 
            _reading_pin(reading_pin), 
            _resistance(resistance), 
            _a(a), _b(b), _c(c) {};
        */

        double steinhart(double r);
        double getTempBudKelvin();
        double getTempBudCelsius();
        double getTempBudFahrenheit();
        double getTempLeafKelvin();
        double getTempLeafCelsius();
        double getTempLeafFahrenheit();
        
    private:
        //Sf110(uint8_t reading_pin, double resistance, double a, double b, double c);
        
        // Value of the resistor put in parallel
        double _resistance;    
        uint8_t _reading_bud;
        uint8_t _reading_leaf;
        uint16_t _adcSize;
        // Manufacturing constants
        double _a;
        double _b;
        double _c;
};

#endif

Sf110.cpp

#include "Sf110.h"
#include <math.h>    

Sf110::Sf110(uint8_t reading_bud, uint8_t reading_leaf, uint16_t adcSize, double resistance, double a, double b, double c)
{
    _reading_bud = reading_bud;
    _reading_leaf = reading_leaf;
    _adcSize = adcSize;
    _resistance = resistance;
    _a = a;
    _b = b;
    _c = c;
}


double Sf110::steinhart(double r)
{
    double log_r  = log(r);
    double log_r3 = log_r * log_r * log_r;

    return 1.0 / (_a + _b * log_r + _c * log_r3);
}

double Sf110::getTempBudKelvin() 
{
    double adc_raw = analogRead(_reading_bud);
    double voltage = adc_raw / _adcSize * V_REF;
    double resistance = ((_adcSize * _resistance / adc_raw) - _resistance);
    
    // Account for dissipation factor K
    return steinhart(resistance) - voltage * voltage / (K * _resistance);
}


double Sf110::getTempBudCelsius() 
{
    return getTempBudKelvin() - 273.15;
}


double Sf110::getTempBudFahrenheit()
{
    return getTempBudCelsius() * 9/5 + 32;
}

double Sf110::getTempLeafKelvin() 
{
    double adc_raw = analogRead(_reading_leaf);
    double voltage = adc_raw / 1024 * V_REF;
    double resistance = ((1024 * _resistance / adc_raw) - _resistance);
    
    // Account for dissipation factor K
    return steinhart(resistance) - voltage * voltage / (K * _resistance);
}


double Sf110::getTempLeafCelsius() 
{
    return getTempLeafKelvin() - 273.15;
}


double Sf110::getTempLeafFahrenheit()
{
    return getTempLeafCelsius() * 9/5 + 32;
}

Je medemande si la taille de cette variable est justifiée

uint16_t adcSize

unit8_t ne serait pas suddisant? Il me semble!!

Mais je suis très intéressé à comprendre cette partie et de savoir comment améliorer ma proposition

/*
                Sf110(
            uint8_t reading_pin, 
            double resistance = 24900.0, 
            double a = 1.129241e-3, //1.129241 X 10 3
            double b = 2.341077e-4,    // 2.34077 X 10 4 
            double c = 8.775468e-8) : 
            _reading_pin(reading_pin), 
            _resistance(resistance), 
            _a(a), _b(b), _c(c) {};
        */

Bonne soirée

Lorsque l’on met des valeurs pour les derniers (un ou plusieurs mais forcément jusqu’à la fin ) paramètres d’une fonction, on peut appeler cette fonction sans préciser ces paramètres ou juste un sous ensemble dans l’ordre et le compilateur l’appelle avec les valeurs par défaut.

Par exemple

void maFonction(int a, [color=purple]int b = 3, int c = 5[/color]) {…}

sera appelable sous la forme

maFonction(10); // a vaudra 10, b vaudra 3 et c vaudra 5

Ou si vous ne voulez pas la valeur par défaut de b

maFonction(10, 42); // a vaudra 10 et b vaudra 42 et c vaudra 5

On peut aussi bien sûr appeler avec 3 paramètres normalement.

Dans la définition du constructeur tel que vous l’avez

 Sf110(
            uint8_t reading_pin, 
            [color=purple]double resistance = 24900.0, 
            double a = 1.129241e-3, //1.129241 X 10 3
            double b = 2.341077e-4,    // 2.34077 X 10 4 
            double c = 8.775468e-8[/color]) [color=red]: 
            _reading_pin(reading_pin), 
            _resistance(resistance), 
            _a(a), _b(b), _c(c) {}[/color];

On a donc des valeurs par défaut pour toutes les variables sauf reading_pin et ce qui se trouve en rouge après les deux points s’appelle une liste d’initialisation. Ça fait comme ce que vous faites en affectant les variables d’instance aux valeurs passées en paramètres (ou celles par défaut ) en le mettant dans le corps de la fonction mais cette écriture est mieux en cas d’héritage pour la précédence de l’ordre d’initialisation des variables d’instance.il est donc habituel d’écrire ainsi l’affectation directe des variables d’instance même si on n’a pas prévu d’héritage.

Quand on sépare la déclaration (dans le .h) de la définition d’une fonction, on met les paramètres par défaut uniquement dans le .h il n’y a pas à les répéter dans le .cpp

Le fait que l’auteur ait prévu un constructeur sans paramètres et qui ne fait rien est de son choix, je suppose qu’il y a des méthodes qui permettent d’affecter les variables d’instances séparément. Ça permet d’instancier l’objet de manière globale en début de code, et ensuite dans le setup() par exemple lui passer des attributs calculés ou en provenance de l’EEPROM ou de l’interface utilisateur etc...

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.