从方法返回对象

Return object from a method c++

本文关键字:对象 返回 方法      更新时间:2023-10-16

我在程序中创建了这个类

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

您正在返回对GeomertyHelper::GetPerpendicularPoint中的临时对象的引用。你应该让这个方法返回一个Node而不是一个Node&,因为当前的方法会导致未定义的行为。

编辑:分配和返回Node*也可以工作。但这应该不是必要的,因为Node对象在返回时可能不会被复制,因为返回值优化。

您正在返回对本地对象的引用。这太糟糕了!!当函数退出时,对象将被销毁,你最终得到的内存不属于你。

Node& GeomertyHelper::GetPerpendicularPoint

当这样做时:

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,否则它将导致内存泄漏

可以返回对所有权为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;
}

注意:这里不需要返回一个指针…我上面的警告真的不适用,你可以只返回值(这是你应该做的)。