为什么这个对象会让人失望?被删除?

时间:2010-04-10 08:11:53

标签: c++ memory

单步执行调试器,BBox对象在函数入口处可以正常,但只要它进入函数,vfptr对象就会指向0xccccc。我不明白。

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

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

     const BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();
    
     boost::unordered_set < Cell*, CellPHash >& l_GridCells = GetGridCells ( &l_Bbox ); 
    

    B中。这就是a_pBoundingBox变得疯狂并获得垃圾值的地方。

     boost::unordered_set< Cell*, CellPHash > CollisionMgr::GetGridCells(const BoundingBox *a_pBoundingBox)
     {
    

    我认为以下代码也是相关的,所以无论如何我都坚持这个:

     const BoundingBox& Player::GetBoundingBox(void)
     {
     return BoundingBox( &GetBoundingSphere() );
     }
    
     const BoundingSphere& Player::GetBoundingSphere(void)
     {
     BoundingSphere& l_BSphere = m_pGeomMesh->m_BoundingSphere;
    
     l_BSphere.m_Center = GetPosition();
    
     return l_BSphere;
     }
    
     // BoundingBox Constructor
     BoundingBox(const BoundingSphere* a_pBoundingSphere);
    

    有人可以告诉我为什么会这样吗?另外,如果您希望我发布更多代码,请告诉我们。

    谢谢!

3 个答案:

答案 0 :(得分:3)

 const BoundingBox& Player::GetBoundingBox(void)
 {
 return BoundingBox( &GetBoundingSphere() );
 }

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

返回BoundingBox而不是BoundingBox&


此外:

 BoundingSphere& l_BSphere = m_pGeomMesh->m_BoundingSphere;

 l_BSphere.m_Center = GetPosition();

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


此外:

 // BoundingBox Constructor
 BoundingBox(const BoundingSphere* a_pBoundingSphere);

在唯一使用引用很有意义的地方,你使用指针代替。为什么呢?

答案 1 :(得分:0)

  1. 正如Thomas所说,BoundingBox是由return语句创建的,并在return语句的末尾被销毁,因为它是一个临时的。返回const引用与分配给持久const引用(确实延长临时引用)不同。返回一个值并将其分配给调用者范围内的某些内容没有因复制省略而产生的开销,尽管您可能需要定义一个复制构造函数。
  2. 如果类具有任何虚方法,例如析构函数,则会创建vtable。如果您的派生类覆盖了这些方法,则需要基本vtable来查找正确的覆盖。所有这些都可能发生在另一个编译单元中,因此编译器不太可能优化它。

答案 2 :(得分:0)

@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

#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的构造函数中有对BoundingSphere的引用而不是指针,即

BoundingBox(const BoundingSphere& a_pBoundingSphere);

要求BoundingSphere的定义在编译时可用。因此,我必须在BoundingBox.h中包含BoundingSphere.h以使定义可用。这适用于反之亦然,从而创建循环引用。

请在此纠正我..

谢谢