Using classmembers as argument for a function

Hello friends,

So i guess for many of you this will be basic stuff. I have ideas how to do it, but i wanna learn it the "right way".

First the facts. Lets say i have a class:

class GsmInput
{
  public:                              
    String phoneNr1;
    String phoneNr2;
    String phoneNr3;
    String message1;
    String message2;
    String smsStatus;
    bool smsStatusForFunction;
    bool dataWasSend = false;
  private:                             
   
};

with a defined object:

GsmInput Testobject;

Now i wanna build a "watchdog" function (that will be in my loop), that will do stuff, depending on the value of bool smsStatusForFunction. This value will change from time to time.

So i was always very lazy with pointers and avoided them. But from what i read, this is the time, where i should use pointers and start to learn. True?

Lets say i will build my watchdog function and do it step by step:

Would this be correct?

byte watchdog (Testobject *vari1)                         //My agrument is a pointer with type of class
{
   testpointer* vari1 = Testobject smsStatusForFunction;  //Pointer points to value of classmember 
   byte value;
   if( testpointer* vari1 == 1){        //Since the pointer points to the value i can operate on them
    //do stuff
      byte = 3;
      return byte;
    }

}

Is it complety stupid what i do?

Thank you very much

Manuel_o:
So i was always very lazy with pointers and avoided them. But from what i read, this is the time, where i should use pointers and start to learn. True?

Personally, I'd use a reference, there's no need for pointers here.

That being said, I do think that if you truly want to understand C++ programming, knowledge of pointers is essential.

Manuel_o:
Would this be correct?

byte watchdog (Testobject *vari1)                         //My agrument is a pointer with type of class

{
  testpointer* vari1 = Testobject smsStatusForFunction;  //Pointer points to value of classmember
  byte value;
  if( testpointer* vari1 == 1){        //Since the pointer points to the value i can operate on them
   //do stuff
     byte = 3;
     return byte;
   }

No, the syntax is not correct. You seem to be confused about the difference between data types and variable names.

byte watchdog (GsmInput *testobj) {  // My agrument is a pointer to GsmInput
   bool vari1 = testobj->smsStatusForFunction;  // Follow the pointer to read the classmember (poor variable name)
   if (vari1) {  // don't compare booleans to integers
      // do stuff 
      byte value = 3;
      return value;
   }
   return 0; // You have to return _something_
}

Using references is easier here, no need for any pointers:

byte watchdog (GsmInput &testobj) {  // My agrument is a reference to GsmInput
   bool vari1 = testobj.smsStatusForFunction;  // Use the usual '.' operator to read the classmember (poor variable name)
   if (vari1) {  // don't compare booleans to integers
      // do stuff 
      byte value = 3;
      return value;
   }
   return 0; // You have to return _something_
}

If your watchdog function is tightly coupled with the GsmInput class, you can make it a member function:

class GsmInput {
  public:
    bool smsStatusForFunction;
    // etc.

    byte watchdog() {
       if (smsStatusForFunction) {
          // do stuff 
          byte value = 3;
          return value;
       }
       return 0; // You have to return _something_
    }
};

Since you don't change any of the values of the GsmInput in your watchdog function, you should take the argument by immutable (const) pointer/reference:

byte watchdog (const GsmInput *testobj) { ... } // first variant: using a pointer

byte watchdog (const GsmInput &testobj) { ... } // second variant: using a reference

class GsmInput {
    byte watchdog () const { ... } // third variant: using a member function
};

Pieter

Thank you sir. very helpful.

Seems i have to dig deeper to gain more understanding

One short question

if (vari1) {… // don’t compare booleans to integers

How would you comapre a bool if true or false? Why is comparing to 1 and 0 bad?

Thank you

Manuel_o:
One short question

if (vari1) {... // don't compare booleans to integers

How would you comapre a bool if true or false?

Because the condition of an if statement should be a boolean expression, and "vari1" is a boolean expression already, so there's no need to compare anything. Comparing a boolean value to "true" is the identity operation, it doesn't change the value:

bool b1 = true;
bool r1 = (b1 == true);
// Both b1 and r1 are true, comparison had no effect
bool b2 = false;
bool r2 = (b2 == true);
// Both b2 and r2 are false, comparison had no effect

So just use the boolean variable directly:

bool someVariable = true;
if (someVariable) {
  Serial.println("someVariable is true");
}

Manuel_o:
Why is comparing to 1 and 0 bad?

Because it doesn't make much sense semantically: a boolean value is either "true" or "false", not "1" or "0", which are integers, not booleans.

The code will do what you want because of how booleans are represented in C++ and because there are implicit conversions between bool and int, but comparing a boolean to 1 or 0 is misleading and unnecessary.

How would you comapre a bool if true or false?

You can also do

if (someBoolean == true)
{
  //do something
}

but sensible naming of boolean variables makes the shorter form equally readable as in

if (ledIsBlinking)
{
  //do something
}

Oh ok. Thank your very much!

I have created this class

class GsmInput
{
  public:                             
    String phoneNr1;
    String phoneNr2;
    String phoneNr3;
    String message1;
    String message2;
    String smsStatus;
    float current_mA = 0;
    
    bool smsStatusForFunction;
    bool SMSdataWasSend = false;


    /************************Fuction***********************************/
    byte handleSendrequest(GsmInput PumpObject)                          
    {
      if(PumpObject.current_mA >= 3 && SMSdataWasSend == false && PumpObject.smsStatusForFunction == true)
      {
        SMSdataWasSend = true;
        return 1;
      }
      else if(PumpObject.current_mA < 3 && SMSdataWasSend == true)
      {
        SMSdataWasSend = false;
         return 0;
      }
    }
    
    /************************************************************/
    void handleByteSendrequest(byte mode)
    {
      switch (mode)
      {
        case 1:
            sendSMSAndEmail_Pump1();
            break;
             
      }

    }
    /************************************************************/

    
  private:                             
   
};

and call the functions in my loop the following

Pump1.handleByteSendrequest(Pump1.handleSendrequest(Pump1));

Is this legit?

Thank you