C ++无法从函数返回对象

时间:2014-04-03 15:07:33

标签: c++ clipperlib

我正在尝试使用C ++“Clipper Library”(http://www.angusj.com/delphi/clipper.php),但是当我尝试从函数中返回clipper库中的一个对象时,它似乎变为null或以某种方式被更改< / p>

这是我写的功能。唯一相关的行应该是最后3行。

ClipperLib::PolyTree MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles)
{
    // Make all of the triangles CW
    for (auto& triangle : triangles)
    {
        triangle.makeClockwise();
    }
    // Set up the Clipper
    ClipperLib::Clipper clipper;
    // To take a union, add all the paths as "subject" paths
    for (auto& triangle : triangles)
    {
        ClipperLib::Path triContour(3);
        triContour[0] = convertGLMToClipperPoint(triangle.getVertex(0));
        triContour[1] = convertGLMToClipperPoint(triangle.getVertex(1));
        triContour[2] = convertGLMToClipperPoint(triangle.getVertex(2));
        clipper.AddPath(triContour, ClipperLib::PolyType::ptSubject, true);
    }
    // Now get the PolyTree representing the contours
    ClipperLib::PolyTree tree;
    clipper.Execute(ClipperLib::ClipType::ctUnion, tree);
    return tree;
}

当我调用clipper.execute时,它会在树结构中写入一些轮廓信息。它写出了正确的信息,我测试过它是正确的。但是,当我返回树时,它似乎没有复制任何东西,并且由此函数产生的PolyTree是空的。

我确信该库没有任何问题,而且我只是在这里犯了一个初学c ++错误。希望有人知道它可能是什么。

谢谢!

编辑:供参考,这是polytree(http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm

的文档页面

编辑:我认为限幅器库不是开源的,但确实如此。这是代码

typedef std::vector< IntPoint > Path;
typedef std::vector< Path > Paths;
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;

class PolyNode 
{ 
public:
    PolyNode();
    Path Contour;
    PolyNodes Childs;
    PolyNode* Parent;
    PolyNode* GetNext() const;
    bool IsHole() const;
    bool IsOpen() const;
    int ChildCount() const;
private:
    unsigned Index; //node index in Parent.Childs
    bool m_IsOpen;
    JoinType m_jointype;
    EndType m_endtype;
    PolyNode* GetNextSiblingUp() const;
    void AddChild(PolyNode& child);
    friend class Clipper; //to access Index
    friend class ClipperOffset; 
};

class PolyTree: public PolyNode
{ 
public:
    ~PolyTree(){Clear();};
    PolyNode* GetFirst() const;
    void Clear();
    int Total() const;
private:
    PolyNodes AllNodes;
    friend class Clipper; //to access AllNodes
};

5 个答案:

答案 0 :(得分:3)

在执行任何操作之前,请确保以下程序正常运行:

int main()
{
   PolyTree p1;
   // fill PolyTree with some values that make sense (please add code to do this)
   //...
   PolyTree p2 = p1; 
   PolyTree p3;
   p3 = p1;
}

这基本上是我们想要测试的。如果您可以使用此代码(添加必要的相关标头和初始化),那么您可以重点关注该功能。如果上面的代码不起作用,那么就有答案。

您需要获取上面的代码才能生成正确的复制语义,甚至是重要的,当main()退出时,在销毁p1,p2和p3时不会发生内存损坏。

因此,要么您可以安全地修复课程,要么忘记课程,并且在有限的情况下必须非常小心地处理课程(即您无法可靠地返回课程副本) 39;现在就做。)

答案 1 :(得分:3)

记录并将冗长讨论中的所有答案与问题结合起来。 问题是:

  1. 返回的值是超出范围的局部变量。这将调用PolyTree析构函数
  2. PolyTree包含PolyNode *指针的向量。调用clipper.Execute()时会分配它们。
  3. 但是,PolyTree :: Clear()会删除节点...并且析构函数会调用Clear()。
  4. 因此在函数内部,内容是正确的(由Execute()分配),当在外部传递时,在没有复制构造函数和operator=的情况下,调用局部变量的析构函数并清除节点,在函数外部收到的结果是空的。
  5. PolyTree :: Clear()

    的代码
    void PolyTree::Clear() 
    {
    for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
          delete AllNodes[i];
        AllNodes.resize(0); 
        Childs.resize(0);
    }
    

    您可能应该遵循执行模式并将您的功能定义为:

    void MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles,ClipperLib::PolyTree &tree) 
    

答案 2 :(得分:2)

假设您不想修改(显然设计糟糕的)Clipper库,您可以像我在评论中建议的那样进行修改:

// Make sure to have this at the top of your header file:
#include <memory>

std::unique_ptr<ClipperLib::PolyTree> MeshHandler::trianglesToPolyTreeUnion(std::vector<Triangle> triangles)
{
    // Rest of your code...

    std::unique_ptr<ClipperLib::PolyTree> tree(new ClipperLib::PolyTree);
    clipper.Execute(ClipperLib::ClipType::ctUnion, *tree);
    return tree;
}

然后,在调用你的函数时:

std::unique_ptr<ClipperLib::PolyTree> tree(yourMeshHandler.trianglesToPolyTreeUnion(/*...*/);

// make use of tree...

不过,我建议打开一张票(如果有错误跟踪器)或联系图书馆的作者有关此问题。

答案 3 :(得分:0)

已经有解决此问题的方法吗?我正在处理同样的问题。 仍然没有运气。多树仅输出内存地址。

使用时:qDebug()<<“ child id” << polynode-> Childs;

当我们有2个孩子时,终端的输出为: std :: vector(0x55f30d2a91b0,0x55​​f30d258480)

我希望有人知道如何解决这个问题。

答案 4 :(得分:-1)

您的问题位于trianglesToPolyTreeUnion底部的第三行。您正在创建的树在堆栈上创建,并且仅在函数范围内。

您应该动态分配内存并返回指向树的指针或使您的树对象成为类成员,以便在函数返回后它仍在范围内。