There is a class containing a container of objects (ships). I want through the class method to change the property of a single object. The method itself returns bool (a sign that the object is found or not), and I want to return the object itself (attention) through the method parameter.

Problem - my FindShip object is deleted when exiting the method. How to make it continue to live?

void SeaGame::PlayerShoot(const Point& In) { Ship FindShip; //создаю временный объект, который нужно изменить if (!ComputerField->FindShipByPoint(In,FindShip)) return; //что-то делаем с объектом FindShip.setDeckByPoint(In, true); } //метод //Result - должен возвращать искомый объект bool FindShipByPoint(const Point& p, Ship& Result) const { for (Ship ship: _ships) //_ships - котейнер stl { for (Point _p : ship.getPoints()) if (p == _p) //реализован соответствующий operator { Result = ship; //реализовано operator= (копирующее присваивание) return true; } } return false; } 

Do I need to do rvalue links here? Or are they nothing to do with?

  • You just have a local object that is destroyed on exit. For something you need it? return it from the PlayerShoot method and save. The semantics of moving here has nothing to do with it. Just at the end of the scope, the object is destroyed ... - Harry
  • Yes, it can still be made static - will it hang in your function, but is that exactly what you need? What do you want to do with it after completing PlayerShoot ? - Harry
  • PlayerShoot is a player's action, it returns nothing (void). In it, the FindShipByPoint method, I want it to do two actions at once - return the bool, and the found object via the 2nd argument (Result). But he is destroyed. I put the question like this - is it possible to return it somehow (and not to destroy it at return) - Sergei Ser
  • I will add it through the argument. Although your implementation below I like! - Sergey Ser

2 answers 2

To change a container object, you need to return a pointer / reference to it. Links can not be zero, so return does not work, and the link to the link in the argument is all the more forbidden. Therefore, it remains only to return a pointer to the desired object (as they do in such situations).


I note that I added an ampersand in a loop on ships and points, so that no copying took place at each iteration and it was possible to return a pointer to a real object, and not a local copy.

 void SeaGame::PlayerShoot(const Point& In) { Ship* FindShip = ComputerField->FindShipByPoint(In); if (!FindShip) return; //что-то делаем с объектом FindShip->setDeckByPoint(In, true); } Ship* FindShipByPoint(const Point& p) const { for (Ship &ship: _ships) // захват по ссылке { for (Point &_p : ship.getPoints()) // аналогично - чтобы не копировать зря if (p == _p) { return &ship; // не нужно ничего копировать, только вернем указатель } } return nullptr; } 

If you really want through the argument:

 void SeaGame::PlayerShoot(const Point& In) { Ship* FindShip; if (!ComputerField->FindShipByPoint(In, FindShip)) return; //что-то делаем с объектом FindShip->setDeckByPoint(In, true); } bool FindShipByPoint(const Point& p, Ship* &result) const { for (Ship &ship: _ships) // захват по ссылке { for (Point &_p : ship.getPoints()) // аналогично - чтобы не копировать зря if (p == _p) { result = &ship; return true; } } return false; } 

Using STL is easier:

 Ship* FindShipByPoint(const Point& p) const { auto it = std::find_if(_ships.begin(), _ships.end(), [&p](Ship& ship){ auto& points = ship.getPoints(); return std::find(points.begin(), points.end(), p) != points.end(); }); return it == _ships.end() ? nullptr : &*it; } 
  • Result = &ship; - swears, "a value of type const Ship * cannot be assigned to Ship *. Result = const_cast <Ship *> (& ship); - Sergei Ser
  • If you want to return a pointer to an object in order to change it later - then the search method should not be designated as const. Otherwise, return const Ship * everywhere, but then the setDeckByPoint method should be const - int3

In my case, no move semantics are needed. Return pointer

 bool FindShipByPoint(const Point& p, Ship* &Result) const { for (const Ship &ship: _ships) { for (const Point &_p : ship.getPoints()) if (p == _p) { Result = const_cast<Ship*>(&ship); // плохо? return true; } } return false; } 
  • Poorly. const_cast intended for other situations - int3