shared ptr — ошибка времени выполнения C ++ с shared_ptr и шаблоном компоновщика

Я изучал язык c ++ с общим указателем и шаблоном построителя

Я написал следующий код, который не работает, но я не понимаю, почему он выдает ошибку во время выполнения.

Не могли бы вы сказать мне, почему это не работает хорошо, и как я могу решить эту проблему, чтобы работать хорошо?

#include <iostream>
#include <memory>
#include <string>

using namespace std;

class Popup
{
public:
Popup(int value, string str){
this->v = value;
this->str = str;
}
virtual void print() = 0;
int v;
string str;
};
typedef shared_ptr<Popup> PopupPtr;

class PopupA : public Popup
{
public:
PopupA(int v, string str) : Popup(v, str) { }
virtual void print() {
cout << "PopupA" << endl;
}
};
typedef shared_ptr<PopupA> PopupAPtr;

class PopupB : public Popup
{
public:
PopupB(int v, string str) : Popup(v, str) { }
virtual void print() {
cout << "PopupB" << endl;
}
};
typedef shared_ptr<PopupB> PopupBPtr;class Builder
{
public:
PopupPtr popupPtr;
Builder() { };
shared_ptr<Builder> init(int value, string str) {
shared_ptr<Builder> builder;

switch (value)
{
case 1:
popupPtr = PopupAPtr(new PopupA(value, str));
break;
case 2:
popupPtr = PopupBPtr(new PopupB(value, str));
break;
default:
cout << "default error" << endl;
break;
}

if (popupPtr) {
builder = shared_ptr<Builder>(this);
}
else {
cout << "popup is null" << endl;
}

if (!builder) {
cout << "builder is null" << endl;
}
return builder;
}

PopupPtr build()
{
if (!popupPtr) {
cout << "popup is null" << endl;
}
return PopupPtr(popupPtr);
}

};
typedef shared_ptr<Builder> BuilderPtr;

int main()
{
BuilderPtr builderPtr = BuilderPtr(new Builder());

PopupPtr popupPtr1 = builderPtr->init(1, "111111111111")->build();
popupPtr1->print();

PopupPtr popupPtr2 = builderPtr->init(2, "222222222222")->build();
popupPtr2->print();
return 0;
}

Заранее спасибо за ваши ответы и извините за мой плохой английский. Если вы не поняли мой вопрос, пожалуйста, оставьте комментарий.

-1

Решение

Ваша проблема в этой строке:

builder = shared_ptr<Builder>(this);

Это будет не создать копию std::shared_ptr уже отслеживание thisи при этом это не повлияет на счетчик ссылок этого. Это создает совершенно новый общий указатель, который будет отслеживать this независимо, вызывая двойное удаление, когда оба счетчика ссылок достигают нуля.

К счастью, стандартная библиотека предоставляет решение этой проблемы в виде std::shared_from_this,

Сначала вам нужно включить это для вашего класса:

class Builder : std::enable_shared_from_this<Builder>
{
//...
};

Тогда вместо создания нового std::shared_ptr от this, вызов std::shared_from_this:

builder = std::shared_from_this();
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]