Reputation: 7
I have a static function where I pass a collider and the other collider is itself. I used a regular pointer before and changed it to shared_ptr
. I can't find a solution to how I can pass this as a shared pointer. Everytime I do something it seems it deletes itself inside the function.
bool RectCollider::CheckCollision(std::shared_ptr<Collider> other, Vector3& normal, float& depth) {
std::shared_ptr<RectCollider> otherRect = std::dynamic_pointer_cast<RectCollider>(other);
std::weak_ptr<RectCollider> thisGo = std::shared_ptr<RectCollider>(this);
if (otherRect) {
if (otherRect == thisGo.lock())
return false;
return Collision::RectCollision(thisGo.lock(), otherRect, normal, depth);
}
std::shared_ptr<CircleCollider> otherCircle = std::dynamic_pointer_cast<CircleCollider>(other);
if (otherCircle) {
return Collision::CircleRectCollision(thisGo.lock(), otherCircle, normal, depth);
}
return false;
}
I'm sure thisGo
is the problem.
I trid to use ChatGPT and it gave me this code and shared_from_this
but it doesn't work.
Upvotes: -1
Views: 238
Reputation: 7
thank you for helping, I figured out what's wrong myself this how I fixed the script
bool RectCollider::CheckCollision(std::shared_ptr<Collider> other, Vector3& normal, float& depth) {
std::shared_ptr<RectCollider> otherRect = std::dynamic_pointer_cast<RectCollider>(other);
std::shared_ptr<Collider> sharedThis = shared_from_this();
if (otherRect) {
if (otherRect == sharedThis)
return false;
return Collision::RectCollision(sharedThis, otherRect, normal, depth);
}
std::shared_ptr<CircleCollider> otherCircle = std::dynamic_pointer_cast<CircleCollider>(other);
if (otherCircle) {
return Collision::CircleRectCollision(sharedThis, otherCircle, normal, depth);
}
return false;
}
Upvotes: 0
Reputation: 1678
std::shared_ptr
has a reference counter, that is, it tracks how many std::shared_ptr
instances point to the same object. Each time a std::shared_ptr
goes out of scope, the counter gets decremented. If it reaches 0, then the object pointed to will be deallocated.
Lets look at a simple example:
#include <memory>
class Obj {
public:
Obj() {
std::shared_ptr<Obj>(this);
}
};
int main() {
Obj o;
return 0;
}
When constructing our Obj
, we create a temporary std::shared_ptr<Obj>
. It will get created, the reference counter gets 1, then (since its temporary) it gets destroyed right again and the reference counter gets decremented to 0. This means that the temporary will try to delete
our object via the this
pointer. But this
was not allocated via new
and delete
-ing memory which was not acquired via new
is UB (undefined behavior).
To avoid this deletion you can supply the std::shared_ptr
constructor with a custom deleter. This deleter will be called (when the refernce counter reaches 0) instead of a plain delete
. If you wrap the this
pointer via a std::shared_ptr
you probably don't want any deallocation to go on so the deleter can be left empty and you could wrap it in a function like the following:
template <typename T>
std::shared_ptr<T> makeThisShared(T* that) {
return std::shared_ptr<T>(that, [](T*) {});
}
Upvotes: 0