【问题标题】:terminate called after throwing an instance of 'std::bad_weak_ptr' what(): bad_weak_ptr?在抛出 'std::bad_weak_ptr' what(): bad_weak_ptr?
【发布时间】:2019-08-31 13:23:13
【问题描述】:

我正在学习智能指针和shared_from_this。在类继承关系中,会非常难理解。

我有两个基类CACB,它们派生自enable_shared_from_this,子类CC 派生自CACB。 我想从类self中取出三个类的共享指针,所以我写了sharedCAfromThissharedCBfromThissharedCCfromthis

class CA  : private enable_shared_from_this<CA> {
public:
    shared_ptr<CA> sharedCAfromThis() { return shared_from_this();  }
    virtual ~CA() {};
    void print() {
        cout << "CA" << endl;
    }
};

class CB : private enable_shared_from_this<CB> {
public:
    shared_ptr<CB> sharedCBfromThis() { return shared_from_this();  }
    virtual ~CB() {};
    void print() {
        cout << "CB" << endl;
    }
};

class CC : public CA, CB {
public:
    shared_ptr<CC> sharedCCfromThis() { return dynamic_pointer_cast<CC>(sharedCAfromThis());  }
    virtual ~CC() {};
    void print() {
        cout << "CC" << endl;
    }
};

int main()
{
    shared_ptr<CC> cc_ptr = make_shared<CC>();
    cc_ptr->sharedCAfromThis()->print();
    //shared_ptr<C> c_ptr = make_shared<C>();
    //c_ptr->get_shared_b()->printb();
    while (1);
}

但我错了问题是:

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'std::bad_weak_ptr'
  what():  bad_weak_ptr

为什么我会收到此错误消息?

你好,是的,非常感谢,我把private改成public了,但是问题依旧存在。我的 gcc 版本是 8.0;我将代码更改如下。

class CA  : public enable_shared_from_this<CA> {
public:
    shared_ptr<CA> sharedCAfromThis() { return shared_from_this();  }
    virtual ~CA() {};
    void print() {
        cout << "CA" << endl;
    }
};

class CB : public enable_shared_from_this<CB> {
public:
    shared_ptr<CB> sharedCBfromThis() { return shared_from_this();  }
    virtual ~CB() {};
    void print() {
        cout << "CB" << endl;
    }
};

class CC : public CA, CB, enable_shared_from_this<CC> {
public:
    shared_ptr<CC> sharedCCfromThis() { return dynamic_pointer_cast<CC>(sharedCAfromThis());  }
    virtual ~CC() {};
    void print() {
        cout << "CC" << endl;
    }
};

【问题讨论】:

  • reference 中不清楚的地方即。公共继承是强制性的 ?
  • 是的,公共继承是强制性的
  • @rafix07 不清楚的部分是根据this reference,从C ++ 17开始才需要,问题没有指定标准版本。
  • @Yksisarvinen 在没有明确指定语言版本的情况下,我认为假设 当前最新版本 是相当合理的 - 目前是 C++17。

标签: c++ inheritance shared-ptr weak-ptr enable-shared-from-this


【解决方案1】:

您应该从enable_shared_from_this 公开继承。每[util.smartptr.shared.const]/1

在下面的构造函数定义中,启用shared_­from_­this 使用p,对于Y* 类型的指针p,意味着如果Y 具有 明确且可访问的基类,它是 enable_­shared_­from_­this,然后remove_­cv_­t&lt;Y&gt;* 应为 隐式转换为 T* 并且构造函数评估 声明:

if (p != nullptr && p->weak_this.expired())
  p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));

weak_­this 成员的赋值不是原子的并且有冲突 对同一对象的任何潜在并发访问 ([intro.multithread])。

如果您使用私有继承,则无法再访问基类。

【讨论】:

  • 谢谢,但是当我将private改为public时,问题依旧存在
  • @justin.shen 那是另一个问题......你可以问一个新问题。
【解决方案2】:

看起来你的问题是你有一个重复。您需要确保只有一个enable_shared_from_this

要对类做到这一点,您可以虚拟地派生类:

class A : virtual public enable_shared_from_this<A> ...
class B : virtual public enable_shared_from_this<B> ...

class C : public A, public B ...

现在您有了enable_shared_from_this&lt;&gt; 的单个实例,这应该可以按预期工作。否则,它可能会使用来自 B 的版本,可能是 nullptr,因此会出现错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多