Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

terminate called after throwing an instance of 'std::bad_weak_ptr' what(): bad_weak_ptr?

Tags:

I'm learning smart pointers and shared_from_this. In Class Inheritance Relations, it will be very hard to understand.

I have two base classes CA and CB, they are derived from enable_shared_from_this, and the child class CC derives from both CA and CB. I want to take out of the three classes shared pointer from the class self, so I write the sharedCAfromThis, sharedCBfromThis and sharedCCfromthis.

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

but I am wrong the problems are:

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

Why am I getting this error message?

hi, yes, thank you very much, I change the private to public, but the problem still exists. my gcc version is 8.0; I change the code as below.

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;
    }
};
like image 397
justin.shen Avatar asked Aug 31 '19 13:08

justin.shen


1 Answers

You should inherit publicly from enable_shared_from_this. Per [util.smartptr.shared.const]/1:

In the constructor definitions below, enables shared_­from_­this with p, for a pointer p of type Y*, means that if Y has an unambiguous and accessible base class that is a specialization of enable_­shared_­from_­this, then remove_­cv_­t<Y>* shall be implicitly convertible to T* and the constructor evaluates the statement:

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

The assignment to the weak_­this member is not atomic and conflicts with any potentially concurrent access to the same object ([intro.multithread]).

If you use private inheritance, the base class is not accessible anymore.

like image 60
L. F. Avatar answered Sep 29 '22 07:09

L. F.