I am having a hard time wrapping around knowing when to use pointers vs references. My question is: in Java/C# you can pass an object as an argument to a function and then assign this argument to an internal class variable so that you can use it outside the scope of the method later on. However, in C++ I am not sure how to achieve the same thing. If I pass by reference, I can only use it within the scope of that method. If I assign the reference to an internal variable of the same type, changes on one don't affect the other. I cannot declare an uninitialized reference either (maybe through constructor). The only solutions I have found are to either pass in the reference every time I need to work with it (as an argument) or pass in a pointer instead once (e.g. through a constructor) and convert it to a reference every time I need to use it outside the scope.
Here is an example method I have for testing this:
- initially the value referenced by get and setValue is set to zero.
- I call Controller2.initialize(Controller &controller, Controller *controllerPtr)
- I call Controller2::process(Controller &controller)
The output is shown after the code blocks below
#include "Controller2.h"
Controller2::Controller2()
{
}
void Controller2::initialize(Controller &controller, Controller *controllerPtr)
{
_controller = controller;
_controllerPtr = controllerPtr;
Controller &controllerRef = *_controllerPtr;
controller.setValue(5);
Serial.println("");
Serial.print("_Controller in initialize(): ");
Serial.print(_controller.getValue());
Serial.print(" Controller in initialize(): ");
Serial.print(controller.getValue());
Serial.print(" Controller Ptr in initialize(): ");
Serial.print(controllerRef.getValue());
Serial.println();
}
void Controller2::process(Controller &controller)
{
Serial.println("");
Serial.print("_Controller in process(): ");
Serial.print(_controller.getValue());
Serial.print(" Controller in process(): ");
Serial.print(controller.getValue());
Controller &controllerRef = *_controllerPtr;
Serial.print(" Controller Ptr in process(): ");
Serial.print(controllerRef.getValue());
Serial.println();
}
Controller2.h:
#include "Arduino.h"
#include "Controller.h"
#ifndef Controller2_h
#define Controller2_h
class Controller2
{
public:
Controller2();
void initialize(Controller &controller, Controller* controllerPtr);
void manage();
void process(Controller &controller);
private:
Controller _controller;
Controller* _controllerPtr;
};
#endif
Controller Class:
#include "Controller.h"
Controller::Controller()
{
}
void Controller::initialize()
{
}
void Controller::setValue(int val)
{
value = val;
}
int Controller::getValue()
{
return value;
}
Controller.h:
#include "Arduino.h"
#ifndef Controller_h
#define Controller_h
class Controller
{
public:
Controller();
void initialize();
void manage();
void setValue(int val);
int getValue();
private:
int value = 0;
};
#endif
And the main class:
#include <Arduino.h>
#include <Controller.h>
#include <Controller2.h>
Controller controller;
Controller2 controller2;
void setup()
{
Serial.begin(115200);
Serial.println("");
Serial.print("Controller initial: ");
Serial.print(controller.getValue());
Serial.println();
controller2.initialize(controller, &controller);
controller2.process(controller);
}
void loop()
{
}
The output results in:
Controller initial: 0
_Controller in initialize(): 0 Controller in initialize(): 5 Controller Ptr in initialize(): 5
_Controller in process(): 0 Controller in process(): 5 Controller Ptr in process(): 5
Is this correct or am I missing something here?