C++ 为什么这个物体会变形;被删除?

C++ 为什么这个物体会变形;被删除?,c++,memory,C++,Memory,逐步通过调试器,BBox对象在函数入口处是正常的,但一旦进入函数,vfptr对象就指向0xccccc。我不明白 这是什么原因造成的 当对象不是从其他类派生时,为什么其中有一个虚拟表引用。(虽然,它驻留在GameObject中,我的Player类从中继承,我从Player中检索BBox。但是,为什么BBox有引用?应该在该引用中维护的不是玩家吗?) 1人;一些代码供参考: A.我从播放器中检索边界框。这将返回预期的边界框。然后我将其地址发送到GetGridCells const Bounding

逐步通过调试器,BBox对象在函数入口处是正常的,但一旦进入函数,vfptr对象就指向0xccccc。我不明白

  • 这是什么原因造成的
  • 当对象不是从其他类派生时,为什么其中有一个虚拟表引用。(虽然,它驻留在GameObject中,我的Player类从中继承,我从Player中检索BBox。但是,为什么BBox有引用?应该在该引用中维护的不是玩家吗?)
  • 1人;一些代码供参考:

    A.我从播放器中检索边界框。这将返回预期的边界框。然后我将其地址发送到GetGridCells

     const BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();
    
     boost::unordered_set < Cell*, CellPHash >& l_GridCells = GetGridCells ( &l_Bbox ); 
    
    谁能告诉我为什么会发生这种事?另外,如果你想让我发布更多的代码,请一定要让我知道

    谢谢

     const BoundingBox& Player::GetBoundingBox(void)
     {
     return BoundingBox( &GetBoundingSphere() );
     }
    
    在这里,您将返回对临时
    边界框
    对象的引用。
    return
    语句一结束,该对象就超出范围

    返回一个
    BoundingBox
    而不是
    BoundingBox&


    此外:

    在这里,您将引用
    m_pGeomMesh
    的边界球体,然后修改它引用的值。这将导致修改原始对象。你确定这就是你想要的吗


    此外:

    在唯一一个使用引用非常有意义的地方,使用指针代替。为什么?

    在这里,您将返回对临时
    边界框
    对象的引用。
    return
    语句一结束,该对象就超出范围

    返回一个
    BoundingBox
    而不是
    BoundingBox&


    此外:

    在这里,您将引用
    m_pGeomMesh
    的边界球体,然后修改它引用的值。这将导致修改原始对象。你确定这就是你想要的吗


    此外:

    在唯一一个使用引用非常有意义的地方,使用指针代替。为什么?

  • 正如Thomas所说,
    BoundingBox
    return
    语句创建,并在return语句末尾销毁,因为它是临时的。返回常量引用与分配给持久常量引用不同(持久常量引用会延长临时引用)。返回一个值并将其分配给调用方作用域中的某个对象不会由于复制省略而产生开销,尽管您可能必须定义一个复制构造函数
  • 如果该类具有任何虚拟方法(如析构函数),则会创建vtable。如果您有重写这些方法的派生类,则需要基本vtable来找到正确的重写。所有这些都可能发生在另一个编译单元中,因此编译器不太可能对其进行优化
  • 正如Thomas所说,
    BoundingBox
    return
    语句创建,并在return语句末尾销毁,因为它是临时的。返回常量引用与分配给持久常量引用不同(持久常量引用会延长临时引用)。返回一个值并将其分配给调用方作用域中的某个对象不会由于复制省略而产生开销,尽管您可能必须定义一个复制构造函数
  • 如果该类具有任何虚拟方法(如析构函数),则会创建vtable。如果您有重写这些方法的派生类,则需要基本vtable来找到正确的重写。所有这些都可能发生在另一个编译单元中,因此编译器不太可能对其进行优化

  • @托马斯:这里有m个班:

    #ifndef BOUNDINGBOX_H
    #define BOUNDINGBOX_H
    
    class BoundingSphere;
    
    class BoundingBox
    {
    public:
    
        BoundingBox(const BoundingSphere* a_pBoundingSphere);
        //BoundingBox( const BoundingBox& rhs);
        virtual ~BoundingBox(void);
    
        const std::vector< glm::vec3 > GetCorners() const;
    
        glm::vec3 m_Center;
        glm::vec3 m_Extents;        // extents along the X, Y, Z axis for the bounding box positioned at the center
    };
    
    #endif
    

    现在,我理解这一点的方式是:如果在BoundingBox的构造函数中有一个对BoundingSphere的引用,而不是指针,即

    BoundingBox(const BoundingSphere& a_pBoundingSphere);
    
    它需要在编译时提供BoundingSphere的定义。因此,我必须在BoundingBox.h中包含BoundingSphere.h以使定义可用。反之亦然,因此创建循环引用

    请纠正我这一点


    谢谢

    @Thomas:这里有m个课程:

    #ifndef BOUNDINGBOX_H
    #define BOUNDINGBOX_H
    
    class BoundingSphere;
    
    class BoundingBox
    {
    public:
    
        BoundingBox(const BoundingSphere* a_pBoundingSphere);
        //BoundingBox( const BoundingBox& rhs);
        virtual ~BoundingBox(void);
    
        const std::vector< glm::vec3 > GetCorners() const;
    
        glm::vec3 m_Center;
        glm::vec3 m_Extents;        // extents along the X, Y, Z axis for the bounding box positioned at the center
    };
    
    #endif
    

    现在,我理解这一点的方式是:如果在BoundingBox的构造函数中有一个对BoundingSphere的引用,而不是指针,即

    BoundingBox(const BoundingSphere& a_pBoundingSphere);
    
    它需要在编译时提供BoundingSphere的定义。因此,我必须在BoundingBox.h中包含BoundingSphere.h以使定义可用。反之亦然,因此创建循环引用

    请纠正我这一点


    谢谢

    你所说的“wonk out”是什么意思?@Eli:当对象到达GetGridCells(..)时,它超出了作用域,因为没有使用正确的术语,这是我的错。你所说的“wonk out”是什么意思?@Eli:当对象到达GetGridCells(..)时,它超出了作用域,因为没有使用正确的术语,这是我的错。但是它返回了一个常量引用。在持有引用的调用方超出范围之前,对象不是保证有效吗?我同意,如果它是非常量引用的话,这将是一个问题。但我模糊地记得常量引用有一个特殊的规则。确实有这样一个规则,但它不适用于这里。对象的
    const
    引用在
    return
    语句中创建,然后作为返回值复制,之后原始
    const
    引用超出范围,对象被销毁。(其他人可能会在技术细节上纠正我,但我很确定这篇
    const
    参考并没有延长任何内容的范围。)托马斯是对的。如果函数返回一个临时值,并且该临时值已绑定到引用,则生存期将延长。但在这种情况下,临时性是函数内部的。考虑如果函数位于两个不同的翻译单元中,则
    #ifndef BOUNDINGBOX_H
    #define BOUNDINGBOX_H
    
    class BoundingSphere;
    
    class BoundingBox
    {
    public:
    
        BoundingBox(const BoundingSphere* a_pBoundingSphere);
        //BoundingBox( const BoundingBox& rhs);
        virtual ~BoundingBox(void);
    
        const std::vector< glm::vec3 > GetCorners() const;
    
        glm::vec3 m_Center;
        glm::vec3 m_Extents;        // extents along the X, Y, Z axis for the bounding box positioned at the center
    };
    
    #endif
    
    #ifndef BOUNDINGSPHERE_H
    #define BOUNDINGSPHERE_H
    
    class BoundingBox;
    
    class BoundingSphere
    {
    public:
        BoundingSphere();
    
    BoundingSphere(const BoundingBox* a_pBoundingBox);
    
        BoundingSphere(const glm::vec3& a_Center, const float& a_Radius);
        virtual ~BoundingSphere(void);
    
        // Access the Center
        const glm::vec3 &GetCenter(void) const  { return(m_Center);     };
        void SetCenter(const glm::vec3 &Center) { m_Center = Center;    };
    
        // Access the Radius
        float GetRadius(void) const     { return(m_Radius);     };
        void SetRadius(float Radius)    { m_Radius = Radius;    };
    
        glm::vec3 m_Center;
        float m_Radius;
    };
    
    #endif
    
    BoundingBox(const BoundingSphere& a_pBoundingSphere);