I started programming in C after a 1-year break, and I am having difficulties here and there (not that I really knew it before the break).
My current problem is that I don't know how to use pointers properly.
I have the following std::vector
:
std::vector<std::shared_ptr<IHittable>> world;
Where IHittable
is the interface of Hittable
objects.
Now, in this std::vector
, multiple derivations of IHittable
are pushed, like Sphere
, Triangle
, etc.
Each of these derived classes has a function intersects()
like this:
Intersection Sphere::intersects(const Ray & ray)
{
auto x = ...
...
return {x, this};
}
Intersection
looks like this:
class Intersection
{
public:
Intersection(double t, IHittable * object);
[[nodiscard]] double t() const;
[[nodiscard]] IHittable * object() const;
private:
double t_;
IHittable * object_ = nullptr;
};
I really don't know how to write this code correctly.
I need to return a this
pointer from the member function intersects()
of an object which is itself allocated dynamically and is stored in a std::shared_ptr
.
Is there a way to handle this?
Another example:
std::vector<std::shared_ptr<IHittable>> world;
world.push_back(std::make_shared<Sphere>());
auto s = Intersection(4.0, world[0]);
Should work.
PS: I could just create multiple std::vector
s without std::shared_ptr
:
std::vector<Sphere> spheres;
std::vector<Triangles> spheres;
...
But IMHO, it would be nice to iterate over every object at once.
PS2: I am now using shared_from_this() and most of my code works, thanks.
CodePudding user response:
I think this sounds like a good fit for std::enable_shared_from_this as Remy pointed out in the comments.
I whipped up a simplified example which hopefully makes it clear how it can be used to achieve what you're after.
class Intersection;
class IHittable : public std::enable_shared_from_this<IHittable> {
public:
virtual Intersection intersects( ) = 0;
virtual void print( ) const = 0;
virtual ~IHittable( ) = default;
};
class Intersection {
public:
Intersection( std::shared_ptr<IHittable> object )
: object_{ std::move( object ) }
{ }
void print_shape( ) const {
object_->print( );
}
private:
std::shared_ptr<IHittable> object_;
};
class Square : public IHittable {
public:
Intersection intersects( ) override {
return Intersection{ shared_from_this( ) };
}
void print( ) const override {
std::cout << "Square\n";
}
};
int main( ) {
std::vector<std::shared_ptr<IHittable>> objects{
std::make_shared<Square>( ) };
const auto intersect{ objects.front( )->intersects( ) };
intersect.print_shape( );
}