ссылка — возврат объекта из метода Stack Overflow

Я создал этот класс в моей программе

node.h

class Node {
private:
std::string id;
double latitude;
double longitude;
public:
Node();
Node(const Node& orig);
Node(std::string id, double lat, double lon);
virtual ~Node();

void SetLongitude(double longitude);
double const & GetLongitude() const;

void SetLatitude(double latitude);
double const & GetLatitude() const;

void SetId(std::string id);
std::string const & GetId() const;
};

node.cpp

    Node::Node() {
}

Node::Node(const Node& orig) {

this->id = orig.id;
this->latitude = orig.latitude;
this->longitude = orig.longitude;
}

Node::~Node() {
}

Node::Node(std::string id, double lat, double lon){
this->id = id;
this->latitude = lat;
this->longitude = lon;
}

void Node::SetLongitude(double longitude) {
this->longitude = longitude;
}

double const & Node::GetLongitude() const {
return longitude;
}

void Node::SetLatitude(double latitude) {
this->latitude = latitude;
}

double const & Node::GetLatitude() const {
return latitude;
}

void Node::SetId(std::string id) {
this->id = id;
}

std::string const & Node::GetId() const {
return id;
}

Я создал метод, который возвращает узел

Node& GeomertyHelper::GetPerpendicularPoint(double pointLat, double pointLon, Node front, Node back) const
{
Node node;
node.SetLatitude(x4);
node.SetLongitude(y4);

return node;
}

тогда я получаю значения из этого метода.

Node projectionPoint = GeomertyHelper::Instance().GetPerpendicularPoint(lat, lon,
Node("",nearestNode.GetLatitude(), nearestNode.GetLongitude()),
Node("",frontNodeLat, frontNodeLon));

double frontNodeLat1 = projectionPoint.GetLatitude();
double frontNodeLon1 = projectionPoint.GetLongitude();

std::cout << std::fixed;
std::cout << std::setprecision(7) << "DIS= Lat------->>>>>" << frontNodeLat1;
std::cout << std::setprecision(7) << "DIS= Lon------->>>>>" << frontNodeLon1 << std::endl;

Но я получаю 0 для значений.

0

Решение

Вы возвращаете ссылку на временный объект в GeomertyHelper::GetPerpendicularPoint, Вы должны позволить методу вернуть Node вместо Node& поскольку текущий метод приводит к неопределенному поведению.

Изменить: выделение и возврат Node* будет работать тоже. Но это не должно быть необходимым, так как Node объект, скорее всего, не будет скопирован при возврате из-за оптимизации возвращаемого значения в любом случае.

2

Другие решения

Вы возвращаете ссылку на локальный объект. Это очень плохо !!!
Объект будет уничтожен при выходе из функции, и вы получите часть памяти, которая не принадлежит вам.

Node& GeomertyHelper::GetPerpendicularPoint
2

Делая это:

Node node;
node.SetLatitude(x4);
node.SetLongitude(y4);

return node;

Вы выделяете узел в стеке, после выхода из функции стек освобождается, так что узел становится недопустимым местом в памяти, и это вызывает неопределенное поведение.

Вы должны вернуть что-то вроде Node* и выделить это с помощью new поэтому он будет находиться в куче и не будет освобожден при выходе из функции:

Node* GeomertyHelper::GetPerpendicularPoint(double pointLat, double pointLon, Node front, Node back) const
{
Node* node = new Node();
node.SetLatitude(x4);
node.SetLongitude(y4);

return node;
}

Но здесь не стоит забывать делать delete node когда вы закончите работать с ним, иначе это приведет к утечке памяти.

1

Вы Можно вернуть ссылку на объект, владельцем которого является безопасный. Я имею в виду, что вы можете вернуть ссылку, если объект гарантированно будет живым во время использования ссылки на объект, которая была возвращена. Это тот случай, если вы использовали объект типа «менеджер», который был жив в течение всего времени жизни процесса.

Проблема в том, что ваш объект является временным, и он будет удален, пока вы пытаетесь его использовать. Вы часто не замечаете этого иногда, так как память, на которую ссылаются, может быть не очищена сразу. Однако в какой-то момент произойдет, что это вызовет сбой или другое странное поведение.

Что касается альтернатив, вы не должны возвращать необработанный указатель IMO, потому что кому «принадлежит» объект в этом случае? Парень, который создал это, или парень, использующий это? Вы должны вернуть std::unique_ptr<Node> вместо. Это делает менее двусмысленным, что код, использующий узел, является владельцем. Это также заставляет вызывающий код решать, что он хочет с ним делать. Он должен быть сохранен в большем объеме или уничтожен.

std::unique_ptr<Node> GeomertyHelper::GetPerpendicularPoint(double pointLat, double pointLon, Node front, Node back) const
{
std::unique_ptr<Node> node( new Node() );
node->SetLatitude(x4);
node->SetLongitude(y4);
return node;
}

НОТА: Возвращение указателя не обязательно здесь … мое замечание выше действительно не применимо, когда вы можете просто вернуть значение (что вы должны сделать здесь).

1
По вопросам рекламы [email protected]