我在程序中创建了这个类
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 :(得分:2)
您正在返回对本地对象的引用。那太糟糕了! 当函数退出时,对象将被销毁,最终得到一块不属于你的内存。
Node& GeomertyHelper::GetPerpendicularPoint
答案 1 :(得分:2)
您将在GeomertyHelper::GetPerpendicularPoint
中返回对临时对象的引用。您应该让方法返回Node
而不是Node&
,因为当前方法会导致未定义的行为。
编辑:分配和返回Node*
也可以。但是这不应该是必要的,因为Node
对象在返回它时可能不会被复制,原因是返回值优化。
答案 2 :(得分:1)
这样做时:
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
,否则会导致内存泄漏。
答案 3 :(得分:1)
您可以返回对所有权为 secure 的对象的引用。我的意思是,如果在使用返回的对象引用期间保证对象处于活动状态,则可以返回引用。如果您使用的“经理”类型对象在整个流程生命周期中都处于活动状态,则会出现这种情况。
问题是您的对象是临时的,并且在您尝试使用它时它将被删除。你们很多人都没有注意到这一点,因为被引用的内存可能无法立即清理掉。但是,它会在某些时候发生,这将导致崩溃或其他一些奇怪的行为。
至于替代方案,你不应该返回一个原始指针IMO,因为在这种情况下谁“拥有”该对象?创造它的人还是使用它的人?您应该返回std::unique_ptr<Node>
。这使得使用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;
}
注意:这里不需要返回指针 ...我上面的警告真的不适用于你可以返回值的地方(这就是你应该做的)在这里)。