考虑以下.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指向的对象将丢失并且错误
在抛出一个实例后终止调用 “增强:: exception_detail :: clone_impl
'what():tr1 :: bad_weak_ptr
被抛出。当以相同的方式调用两个重载函数(Init)时,不会发生同样的情况。
有人可以解释一下吗?
答案 0 :(得分: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) {...}
...否则你必须声明另一个函数并让两个构造函数都调用它。