Перегрузка конструктора с помощью boost :: shared_ptr

Рассмотрим следующий файл .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

‘что (): tr1 :: bad_weak_ptr

брошен Этого не происходит при одинаковом вызове двух перегруженных функций (Init).

Может кто-нибудь, пожалуйста, объясните это?

1

Решение

Проблема в том, что вы вызываете shared_from_this () во время построения B, что запрещено, потому что общий указатель на 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) {...}

… В противном случае вы должны объявить другую функцию, и оба конструктора вызовут ее.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]