2016-09-04 3 views
4

Я работаю над небольшим компонентом игрового движка на C++. Различные компоненты добавляются во внутренний список объекта геймобжекты, чтобы сэкономить время, я не сделать переменную-член этих компонентов, только объект игры является переменной-члена, например, так:C++ дизайн игрового движка и объекты, выходящие из области действия

void Initialize() 
{  
    MeshComponent* meshRenderer = new MeshComponent(mesh, material); 
    m_GameObject.AddComponent(meshRenderer); 
} 

meshRenderer переменная добавляется в список компонентов в AddComponent(), но выходит за пределы области действия в конце этой функции.

Позже (в обновлении/рисовании цикла) этот компонент вызывается и все работает, несмотря на то, что объект вышел из области во время инициализации.

Насколько я понимаю, что-то не так в области видимости, безопасно ли это использовать или есть другой подход, который я должен предпринять (без необходимости вносить переменные-члены каждого из моих компонентов)?

Спасибо за помощь!

+0

Я настоятельно рекомендую использовать make_shared <> (общий указатель) или make_unique <>, или, по крайней мере, узнать о них вместо «нового» и «удалить». – Robinson

ответ

1

Прежде всего, я предлагаю вам изучить C++ еще до начала крупных проектов, таких как игровой движок.

Что выходит за пределы области действия является переменной meshRenderer, которая имеет тип MeshComponent*, то есть указатель на MeshComponent. Что происходит, когда указатель выходит из области видимости? Ничего. Память была выделена в куче с помощью оператора new, и он останется там до тех пор, пока вы не освободите его, используя оператор delete.

0

Позже (в обновлении/рисовании цикла) этот компонент вызывается, и все работает, несмотря на то, что объект вышел из области действия во время инициализации.

Этот компонент не выходит за пределы сферы действия, если не находится delete d в другом месте.

1

Позже (в обновлении игры/ничья петли) этот компонент называется и все работает, несмотря на объект уйдя из области видимости во время инициализации.

Это потому, что в блоке:

void Initialize() 
{  
    MeshComponent* meshRenderer = new MeshComponent(mesh, material); 
    m_GameObject.AddComponent(meshRenderer); 
} 

переменная в стеке является указателем (meshRenderer), заостренный объект выделяется на кучного. Итак, когда } достигнут только указатель «разрушен», но не заострённый предмет.

Это одна из причин, повлекшая за собой ошибки в динамической памяти.

Поэтому он должен работать «правильно» , пока менеджер компонентов не обработает правильно динамическую память (например, надлежащее освобождение).


можно безопасно использовать, как это или есть другой подход, который я должен принять (без того, чтобы сделать переменные-члены каждого из моих компонентов)?

Безопасное относительное понятие. Даже тот, кто имеет большой опыт работы в динамической памяти C или C++, может ошибаться, производя утечки памяти.

Предлагаю вам прочитать и узнать smart pointers. [c C++ 11]

Умный указатель упрощает концепцию указателя, потому что (при правильном использовании) он автоматически обрабатывает освобождение памяти.

В вашем случае, например, может использоваться std::shared_ptr.

A общий указатель позволяет использовать несколько экземпляров указателей, которые ссылаются на один и тот же объект (одна и та же память). Действительно, несколько объектов std::shared_ptr могут иметь один и тот же объект. Объект уничтожается и его память освобождается, когда последний оставшийся shared_ptr, владеющий объектом, уничтожается (или явно хочет программист).

+0

+1 Хотя я бы использовал unique_ptr, или был бы строгим в отношении права shared_ptr и только возвращал weak_ptr пользователям. Обратите внимание, что это не очень популярно у пуристов, которые видят проблемы производительности, скрывающиеся за каждым умным указателем. – Robinson

+1

@ Robinson Я совершенно согласен с тобой. Действительно, я редко использую интеллектуальные указатели, но мой сценарий работы всегда связан с алгоритмом низкого уровня. В игровом движке вместо этого я вижу их много, особенно в * Системе компонентов *, часто используется общий указатель *. Вот почему я вкратце предложил это. –