首页 > 解决方案 > 将原始指针指向 shared_ptr

问题描述

我在休息 1 年后开始使用 C++ 编程,但我在这里和那里都遇到了困难(并不是说我在休息之前真的知道它)。

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

我有以下内容std::vector

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

IHittable对象的接口在哪里Hittable

现在,在 this中,推送std::vector了 的多个派生,例如,等。IHittableSphereTriangle

这些派生类中的每一个都有这样的功能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;
};

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

我需要从对象的成员函数返回一个this指针,intersects()该对象本身是动态分配的并存储在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::vectors 而没有std::shared_ptr

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

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

PS2:我现在正在使用 shared_from_this() 并且我的大部分代码都可以工作,谢谢。

标签: c++oopinheritancepolymorphismshared-ptr

解决方案


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

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

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

推荐阅读