将其转换为共享指针,并将其作为参数传递给另一个C++类

Converting this to shared pointer and passing it as an argument to another C++ class

本文关键字:另一个 C++ 参数传递 转换 共享 指针      更新时间:2023-10-16

我正在使用以下框架编写代码:

class IFirstStep // abstract interface
{
public:
    virtual commonMethod1() = 0;
    ...
};
class FirstStepBase : public IFirstStep // Jobs common to all FirstStep's
{
public:
    FirstStepBase() {}
    commonMethod1() override;
    ...
protected:
    CommonMembers;
    void correctSettings()
    {
        somePreparations;
        auto smartPtr = static_cast<std::shared_ptr<IFirstStep>>(this);
        SecondStep secondStep(smartPtr);
        some calculations using secondStep;
        reassignment of some of commonMembers;
    }
};
class FirstStep1 : public FirstStepBase
{
public:
    FirstSiep1(bool fineTune)
    {
        commonMembers = initilizeSettings();
        if (fineTune)
            correctSettings();
    }
private:
    CommonMembers initilizeSettings() {calculate and assign commonMembers;}
};
class FirstStep2 : public FirstStepBase
...
class FirstStepN : public FirstStepBase
...
class SecondStep
{
public:
    SecondStep(std::shared_ptr<IFirstStep> & firstStep) : m_firstStep(firstStep) {}
    some methods which use firstStep and return some results;
    firstStep itself is not changed;
};

correctSettings(( 完美执行,纠正了 FirstStep1 的所有设置,但在退出 correctSettings(( 时在 MS VS 调试器中崩溃,并带有诊断:

File: minkernelcrtsucrtsrcappcrtheapdebug_heap.cpp
Line: 888
Expression: _CrtIsValidHeapPointer(block)

看起来问题是由强制转换引起的 - 即使在转换后立即执行退出,代码也会崩溃。MS VS 编译器不接受其他类型的强制转换,包括指针强制转换。但是,如果按如下方式更改 rightSettings(( 并将适当的构造函数添加到 FirstStepBase 中,则事情可以完美运行

void correctSettings()
{
    std::shared_ptr<IFirstStep> smartPtr 
        = <std::make_shared<FirstStepBase>>(commonMembers);
    SecondStep secondStep(smartPtr);
    some calculations using secondStep;
    reassignment of some of commonMembers;
}

我将非常感谢解释为什么第一种方法失败,以及是否有可能在代码中使用此指针而不是生成额外的 FirstStepBase 对象?请假设不可能将接口更改为第二步。谢谢。

在你的第一种方法中,你的this只是一个原始指针,但你试图把它转换为一个具有不同大小、不同结构的shared_pointer。

要解决此问题,您可以尝试使用 boost::enable_shared_from_this ,这将允许您从其自己的函数中检索对象的共享指针。然后,您不必构造另一个 FirstStepBase 对象。你可以看看这里boost_shared_from_this

不能将原始对象指针直接类型转换为std::shared_ptr

但是,您可以做的是从std::enable_shared_from_this派生FirstStepBase,然后FirstStepBase可以在需要时调用shared_from_this(),例如:

class FirstStepBase : public std::enable_shared_from_this<FirstStepBase>, public IFirstStep // Jobs common to all FirstStep's
{
    ...
    void correctSettings()
    {
        ...
        auto smartPtr = shared_from_this(); // <-- here
        SecondStep secondStep(smartPtr);
        ...
    }
};

仅当FirstStep...对象由std::shared_ptr管理时,此操作才有效,因此请确保在创建FirstStep...对象时始终使用 std::shared_ptr

另一方面,如果SecondStep不是为了比它关联的FirstStep...对象更长久,那么就没有理由一开始就给它传递一个std::shared_ptr<IFirstStep>,只需向它传递一个原始的IFirstStep*指针:

class SecondStep
{
private:
    IFirstStep *m_firstStep;
public:
    SecondStep(IFirstStep *firstStep) : m_firstStep(firstStep) {}
    ...
};

仅当SecondStep的寿命超过所有引用并需要使对象保持活动状态时,传递std::shared_ptr才有意义FirstStep...

">

this"被强制转换为共享指针,但在这种情况下,它不是原始指针吗

相关文章: