【问题标题】:Constructor overloading with boost::shared_ptrboost::shared_ptr 的构造函数重载
【发布时间】:2012-09-18 11:27:16
【问题描述】:

考虑以下 .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

'what(): tr1::bad_weak_ptr

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

谁能解释一下?

【问题讨论】:

    标签: c++ boost shared-ptr


    【解决方案1】:

    问题是你在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) {...}
    

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

    【讨论】:

    • 好吧,你是对的!我编辑了代码,以便您提到的构造函数调用未调用 shared_from_this() 的重载构造函数。现在我收到断言失败的错误:(px != 0), function operator->, file /usr/local/include/boost/smart_ptr/shared_ptr.hpp, line 414。
    • 就在那儿,我编辑了原始帖子。构造函数不再调用 Init,它调用 B(2, a_ptr)。 B::B(boost::shared_ptr&lt;A&gt; a_ptr) { B(2, a_ptr); }
    • @apon 好的,我想我看到了另一个问题,请参阅我的答案编辑。
    • 好的,这就解释了!非常感谢!
    猜你喜欢
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多