У меня есть держатель класса H
с unique_ptr
для экземпляра класса A
(H
является владельцем A
). Класс A
определяет вложенный класс B
и имеет unique_ptr
для экземпляра B
(A
является владельцем B
). В свою очередь, экземпляр A
B
должен обновить аспекты своего A
, и поэтому B
имеет необработанный указатель на A
, которому он принадлежит.
Моя проблема в том, чтокогда члены A обновляются, B не может их точно вернуть. Когда B создается, и его указатель на принадлежащий ему A создается, его указатель выходит из области видимости.
Я могу заставить это работать, когда класс держателя отсутствует (то есть A не принадлежит никому, но все еще указан его экземпляром B).
Рассмотрим этот код:
#include <iostream>
#include <vector>
#include <memory>
// define class A
class A{
public:
A(int x, int y);
// define class B within A
class B {
public:
B(A& a, int y);
private:
int b_y;
A* b_a;
public:
void update_B(){
std::cout << "Updating y of B belonging to A with x value " << b_a->a_x << std::endl;
b_y += 1;
}
}; // end of class B
private:
int a_x;
std::unique_ptr<B> a_b;
public:
void update_A(){
std::cout << "Updating A...";
a_x += 1;
std::cout << " A's x is now " << a_x << std::endl;
a_b->update_B();
}
}; // end of class A
// define class H
class H{
public:
H(int x, int y);
private:
std::unique_ptr<A> h_a;
public:
void update_h(){
h_a->update_A();
}
}; // end of class H
// define class A's constructor
A::A(int x, int y) {
std::cout << "...creating instance of A... " << std::endl;
a_x = x;
a_b = std::make_unique<B> (B(*this, y)); // assign the unique ptr to B
std::cout << "...A's x is set to " << x << std::endl;
}
// define class B's constructor
A::B::B(A& a, int y) {
std::cout << ":- Creating instance of B within A..." << std::endl;
b_a = &a; // assign B's pointer to the A instance that called it
b_y = y;
std::cout << ":- ...B's y is set to " << b_y << std::endl;
std::cout << ":- ...B belongs to an A with value " << b_a->a_x << std::endl;
}
// define class H's constructor
H::H(int x, int y){
std::cout << "Creating instance of H" << std::endl;
h_a = std::make_unique<A> (A(x, y)); // assign the unique ptr to A
}
// main function
int main()
{
// create instance of H
H h(2, 10);
// update the H function, which calls update_A and update_y
h.update_h();
return 0;
}
Ожидаемый результат:
Creating instance of H
...creating instance of A...
:- Creating instance of B within A...
:- ...B's y is set to 10
:- ...B belongs to an A with value 2
...A's x is set to 2
Updating A... A's x is now 3
Updating y of B belonging to A with x value 3
, но фактический результат:
Creating instance of H
...creating instance of A...
:- Creating instance of B within A...
:- ...B's y is set to 10
:- ...B belongs to an A with value 2
...A's x is set to 2
Updating A... A's x is now 3
Updating y of B belonging to A with x value <some massive number>
Кажетсячто B не отслеживает экземпляр A, на который он первоначально указывал.
Я могу заставить код работать, явно передав *this
функции B
update_B()
, например update_B(A& a){ b_a = &a; }
, но я не понимаю, почему вышеприведенное не работает.
Большое спасибо за понимание.