What is happening with this Class Composition?

Hello everyone! Thank you all for reading! I am building a IP PDU (Power Distribution Unit - aka IP power stick, IP powerbar). I am using an Arduino UNO R3 and an Ethernet Shield. I have two classes in my code. One for the Outlets, the other for the Powerbar itself. I had written several lines of code and I have it working already but I came across this issue while improving the code... (or I thought I was improving it) :wink:

The Powerbar class has an array of Outlets, here is the class composition.
It also has a method getOutlet(byte index) which returns an Outlet object, the one that is in the "index" position of the array.
Every outlet in the powerbar has a name (only 8 chars + null). This name is shown in the web page under the image of the outlet. An Outlet object has a getName and setName method for getting and setting this name. But writing:
powerbar.getOutlet(0).setName("newname") doesn't change the outlet name! Don't know why!
But if I add a new method to the powerbar class setOutletName(byte index, char *newName) this one works as expected.

For better understanding I made a simplified sketch showing the issue:

class Outlet {
  public:
  Outlet(byte pin) : _pin(pin), _name{"ini"} {}
  
  char* getName() {
    return _name;
  }
  void setName(char *newName) {
    strcpy(_name, newName);
  }

  private:
  byte _pin;
  char _name[9];
};

class Powerbar {
  public:
  Powerbar(byte pin) : _outlets{Outlet(pin)} {}
  
  Outlet getOutlet(byte index) {
    return _outlets[index];
  }

  void setOutletName(byte index, char *newName) {
    _outlets[index].setName(newName);
  }

  private:
  Outlet _outlets[1];
};


Powerbar pbar(8);


void setup() {
  Serial.begin(9600);
}

void loop() {
  Outlet outlet = pbar.getOutlet(0);
  outlet.setName("name_1");
  Serial.println(pbar.getOutlet(0).getName());
  
  pbar.getOutlet(0).setName("name_2");
  Serial.println(pbar.getOutlet(0).getName());

  // the only way it works
  pbar.setOutletName(0, "name_3");
  Serial.println(pbar.getOutlet(0).getName());
}

Your getOutlet() method returns an Outlet object, NOT a pointer to an Outlet object.

powerbar.getOutlet(0).setName("newname") doesn't change the outlet name!

It most certainly does. But, that Outlet object, with the new name, goes out of scope.

The getOutlet() method needs to return a pointer to an Outlet instance, and the _outlets field should be an array of pointers, not an array of instances.

Maybe return a reference to the indexed Outlet?

Outlet & getOutlet(byte index) {
    return _outlets[index];
}

Thank you guys very much!!! I chose the answer of gfvalvo and it works like a charm!!!
Here it is the working code:

class Outlet {
  public:
  Outlet(byte pin) : _pin(pin), _name{"ini"} {}
  
  char* getName() {
    return _name;
  }
  void setName(char *newName) {
    strcpy(_name, newName);
  }

  private:
  byte _pin;
  char _name[9];
};

class Powerbar {
  public:
  Powerbar(byte pin) : _outlets{Outlet(pin)} {}
  
  Outlet* getOutlet(byte index) {
    return & _outlets[index];
  }

  void setOutletName(byte index, char *newName) {
    _outlets[index].setName(newName);
  }

  private:
  Outlet _outlets[1];
};


Powerbar pbar(8);


void setup() {
  Serial.begin(9600);
}

void loop() {
  // NOW THIS WORKS !!!
  pbar.getOutlet(0)->setName("name_2");
  Serial.println(pbar.getOutlet(0)->getName());

  // this also works
  pbar.setOutletName(0, "name_3");
  Serial.println(pbar.getOutlet(0)->getName());
}
  void setName(char *newName) {
    strcpy(_name, newName);
  }

You REALLY should be using strncpy() to assure that you don't write more to _name than it can hold.

  pbar.getOutlet(0)->setName("This name is absolutely going to cause you problems");