-1

I have a question about pointers and references in C++. I am a programmer who normally programs in C# and PHP.

I have two classes (for now) which are the following. The X/Y in Controller are continuously changing but i want them up to date in the Commands. I have multiple commands like Forward, Turn, Backward etc.

When i make the commands i give them the controller but the state (X, Y) of the controller are updating every second.

How can i fix that the controller attribute in the Commands are getting updated also every second?

class Forward : ICommand
{
    Controller ctrl;

    void Execute() {
        int CurrentX = ctrl.X;
        int CurrentY = ctrl.Y;
        //Check here for the current location and calculate where he has to go. 
    }
}

class Controller 
{
    int X; 
    int Y; 

    void ExecuteCommand(ICommand command) {
        command.Execute();
    }
}

Main.cpp

Controller controller;

Forward cmd1 = new Forward(1, controller);
Turn cmd2 = new Turn(90, controller);
Forward cmd3 = new Forward(2, controller);

controller.Execute(cmd1);
controller.Execute(cmd2);
controller.Execute(cmd3);

I have read something about pointers and references and i think i have to use this but don't know how to use it in this situation.

(code can have some syntax errors but that's because i typed over. Everything is working further except for the updating).

  • 2
    There is no need for the `new`, you can just allocate that with `Forward cmd1(1, controller);`. Otherwise you would need to have a `delete` and use pointers like `Forward *cmd1 = new Forward(1, controller);`. — Then your `Forward` has a *copy* of `controller`, therefore all changes to not propagate back to `controller` in `main`. You need to have `Controller &ctrl` in `Forward`, then you can update the variables of your `controller` in `main`. – Martin Ueding Mar 28 '17 at 13:11
  • ... and be careful with the constructor signature (which you haven't shown) – doctorlove Mar 28 '17 at 13:12

1 Answers1

1

If you use references rather than copy objects you can see changes.

#include <iostream>
using namespace std;

class ICommand
{
public:
    virtual ~ICommand() = default;
    virtual void Execute() = 0;
};

class Controller
{
public:
    int X = 0;
    int Y = 0;

    void ExecuteCommand(ICommand & command) {
        //                       ^-------
        command.Execute();
    }
};//,--- semicolons required

class Forward : public ICommand //note public
{
    const int step;
    Controller ctrlCopy;
    Controller & ctrlReference;

public:
    Forward(int step, Controller & ctrl) :
        step(step),
        ctrlCopy(ctrl),      //this is a copy of an object
        ctrlReference(ctrl)  //this is a reference to an object
    {

    }

    void Execute() {
        std::cout << "copy: " << ctrlCopy.X << ", " << ctrlCopy.Y << '\n';
        std::cout << " ref: " << ctrlReference.X << ", " << ctrlReference.Y << '\n';
        //Check here for the current location and calculate where he has to go. 
        ctrlCopy.X += 10;
        ctrlReference.X += 10;
    }
};//<--- semicolons required


int main() {
    Controller controller;

    Forward cmd1(1, controller);
    //Turn cmd2(90, controller); //Left for the OP to do
    Forward cmd3(2, controller);

    controller.ExecuteCommand(cmd1);
    //controller.ExecuteCommand(cmd2);
    controller.ExecuteCommand(cmd3);

    //Do it again to show the copy and reference difference
    std::cout << "Once more, with feeling\n";
    controller.ExecuteCommand(cmd1);
    controller.ExecuteCommand(cmd3);
}

Giving

copy: 0, 0
 ref: 0, 0
copy: 0, 0  // [1]
 ref: 10, 0 // [2]
Once more, with feeling
copy: 10, 0
 ref: 20, 0
copy: 10, 0
 ref: 30, 0

1 shows that the copy has X and Y of 0, while the reference shown in [2] has moved by the stated step (in controller.ExecuteCommand(cmd3))

Note, we don't need to use new to make this work (don't forget delete if you use new).

Also, void ExecuteCommand(ICommand command) now takes a reference instead otherwise the by-value copy does "slicing" (e.g. see here)

Community
  • 1
  • 1
doctorlove
  • 18,872
  • 2
  • 46
  • 62