将原始指针指向 shared_ptr

Point raw pointer to a shared_ptr

我在中断 1 年之后开始使用 C++ 进行编程,但我遇到了一些困难(并不是说我在中断之前就真的知道了)。

我现在的问题是不知道如何正确使用指针。

我有以下 std::vector:

std::vector<std::shared_ptr<IHittable>> world;

其中 IHittableHittable 个对象的接口。

现在,在这个 std::vector 中,IHittable 的多个派生被推送,例如 SphereTriangle

这些派生的每个 类 都有一个函数 intersects(),如下所示:

Intersection Sphere::intersects(const Ray & ray)
{
    auto x = ...
    ...
    return {x, this};
}

Intersection 看起来像这样:

class Intersection
{
    public:
        Intersection(double t, IHittable * object);
        [[nodiscard]] double t() const;
        [[nodiscard]] IHittable * object() const;
    private:
        double t_;
        IHittable * object_ = nullptr;
};

我真的不知道如何正确编写这段代码。

我需要 return 来自对象成员函数 intersects()this 指针,该对象本身是动态分配的,并存储在 std::shared_ptr 中。

有办法处理吗?

另一个例子:

std::vector<std::shared_ptr<IHittable>> world;
world.push_back(std::make_shared<Sphere>());
auto s = Intersection(4.0, world[0]);

应该可以。

PS:我可以在没有 std::shared_ptr 的情况下创建多个 std::vector

std::vector<Sphere> spheres;
std::vector<Triangles> spheres;
...

但是恕我直言,一次遍历每个对象会很好。

PS2:我现在正在使用 shared_from_this() 并且我的大部分代码都有效,谢谢。

正如雷米在评论中指出的那样,我认为这听起来很适合 std::enable_shared_from_this

我制作了一个简化的示例,希望它能清楚地说明如何使用它来实现您的目标。

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( );
}