我正在使用以下框架编写代码:
fromString
correctSettings()完美地执行了更正FirstStep1的所有设置,但在使用诊断程序从correctSettings()退出时在MS VS调试器中崩溃:
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;
};
看起来问题是由于代码崩溃引起的 - 即使在转换后执行退出也是如此。 MS VS编译器不接受其他类型的转换,包括指针转换。但是,如果将correctSettings()更改为如下并且将相应的构造函数添加到FirstStepBase
,那么这个东西可以完美地运行File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 888
Expression: _CrtIsValidHeapPointer(block)
我非常感谢第一种方法失败的原因并且可以在代码中使用这个指针而不是生成一个额外的FirstStepBase对象。请假设没有可能将界面更改为SecondStep。 谢谢。
答案 0 :(得分:1)
在你的第一种方法中,你的this
只是一个原始指针,但是你试图将它转换为`shared_pointer,它具有不同的大小,不同的结构。
要解决此问题,您可以尝试使用boost::enable_shared_from_this
,这将允许您从其自己的函数中检索对象的共享指针。然后您不必构造另一个FirstStepBase对象。
你可以看看boost_shared_from_this
答案 1 :(得分:1)
您无法直接将原始对象指针转换为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
开始管理时才有效,因此请确保在创建std::shared_ptr
对象时始终使用FirstStep...
。< / p>
另一方面,如果SecondStep
并不意味着超过其关联的FirstStep...
对象,那么没有理由将std::shared_ptr<IFirstStep>
传递给它开始,只需将其传递给它改为原始IFirstStep*
指针:
class SecondStep
{
private:
IFirstStep *m_firstStep;
public:
SecondStep(IFirstStep *firstStep) : m_firstStep(firstStep) {}
...
};
只有std::shared_ptr
超过所有SecondStep
引用并且需要保持对象存活,才能传递FirstStep...
。
答案 2 :(得分:0)
“this”被转换为共享指针,但在这种情况下不是原始指针