1

考虑以下 .h 文件:

#ifndef COM_H_
#define COM_H_

#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <map>

class B;

class A : public boost::enable_shared_from_this<A>{
public:
    A(){}
    ~A(){}

    void Init();

    boost::shared_ptr<B> b_ptr_;
};

class B : public boost::enable_shared_from_this<B>{
public:

    B(){}
    B(boost::shared_ptr<A> a_ptr);
    B(int j, boost::shared_ptr<A> a_ptr);
    ~B(){}

    void Init();
    void Init(boost::shared_ptr<A> a_ptr);
    void Init(int j, boost::shared_ptr<A> a_ptr);

    std::string b;
    boost::shared_ptr<A> a_ptr_;
};
#endif /* COM_H_ */

和 .cc 文件:

#include "com.h"

void A::Init() {

    // Case 1 not working
    // boost::shared_ptr<B> b1(new B(shared_from_this()));
    // b1->Init();

    // Case 2 working
    boost::shared_ptr<B> b2(new B());
    b2->Init(shared_from_this());
}

B::B(boost::shared_ptr<A> a_ptr) {
    B(2, a_ptr);
}

B::B(int j, boost::shared_ptr<A> a_ptr) {
    a_ptr_ = a_ptr;
    b = "b";
}

void B::Init() {
    a_ptr_->b_ptr_ = shared_from_this();
}

void B::Init(boost::shared_ptr<A> a_ptr) {
    Init(2, a_ptr);
}

void B::Init(int j, boost::shared_ptr<A> a_ptr) {

    a_ptr_ = a_ptr;
    b = "b";
    a_ptr_->b_ptr_ = shared_from_this();
}

主要:

#include "com.h"
#include <iostream>
int main() {

    boost::shared_ptr<A> a(new A());
    a->Init();

    std::cout << a->b_ptr_->b << std::endl;

    return 0;
}

将 boost::shared_ptr 传递给构造函数,然后使用与参数相同的指针调用另一个(重载)构造函数时,shared_ptr 指向的对象丢失并且错误

在抛出 'boost::exception_detail::clone_impl 的实例后调用终止

' 什么(): tr1::bad_weak_ptr

被抛出。以相同方式调用两个重载函数 (Init) 时不会发生同样的情况。

谁能解释一下?

4

1 回答 1

0

问题是您在 B 的构造期间调用 shared_from_this() ,这是被禁止的,因为当时尚未初始化指向 B 的共享指针。

具体来说,这个构造函数就是你调用的那个:

B::B(boost::shared_ptr<A> a_ptr) {
    Init(2, a_ptr);  // runtime error -- Init(...) calls shared_from_this!
}

回答第 2 部分:

我怀疑你已经习惯了另一种语言:) 在 C++ 中,你不能以你试图做的方式调用另一个构造函数。线

B(2, a_ptr);

没有按照你的想法做——它所做的只是构建一个立即被销毁的临时 B 对象。它不会调用其他构造函数。因此,您最终得到的 B 仍然具有默认构造的 a_ptr_ 成员。

如果您的编译器支持 C++-11,它具有委托构造函数,如下所示:

B(shared_ptr<A> a_ptr) : B(2, a_ptr) {...}

...否则,您必须声明另一个函数并让两个构造函数都调用它。

于 2012-09-18T14:03:19.953 回答