Почему этот объект выходит из строя и удаляется? - PullRequest
0 голосов
/ 10 апреля 2010

Проходя через отладчик, объект BBox в порядке при вводе функции, но как только он входит в функцию, объект vfptr указывает на 0xccccc. Я не понимаю

  1. Что вызывает это?
  2. Почему там ссылка на виртуальную таблицу, если объект не является производным от другого класса. (Хотя он находится в GameObject, от которого наследуется мой класс Player, и я извлекаю BBox из проигрывателя. Но почему у BBox есть ссылка? Разве это не должен быть игрок, которого следует поддерживать в этой ссылке?)

за 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 ]

3 голосов
/ 10 апреля 2010
 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);

Единственное место, где использование ссылки имеет большой смысл, вместо этого вы используете указатель. Почему?

0 голосов
/ 11 апреля 2010

@ Томас: Вот 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 было доступно во время его компиляции. Таким образом, мне придется включить BoundingSphere.h в BoundingBox.h, чтобы сделать определение доступным. Это верно для обратного и, таким образом, создает циклические ссылки.

Пожалуйста, поправьте меня в этом ..

Спасибо

0 голосов
/ 10 апреля 2010
  1. Как говорит Томас, BoundingBox создается оператором return и уничтожается в конце оператора return, потому что он временный. Возврат константной ссылки - это не то же самое, что присвоение постоянной константной ссылки (которая продлевает временную). Возврат значения и присвоение его чему-либо в области видимости вызывающей стороны не требует дополнительных затрат из-за исключения копирования, хотя может потребоваться определить конструктор копирования.
  2. vtable создается, если у класса есть какие-либо виртуальные методы, такие как деструктор. Если бы у вас были производные классы, которые переопределяли эти методы, базовый vtable должен был бы найти правильное переопределение. Все это может произойти в другом модуле компиляции, поэтому компилятор вряд ли его оптимизирует.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...