gpt4 book ai didi

c++ - 嵌套类的原始指针类成员无法返回分配的指向对象的数据

转载 作者:行者123 更新时间:2023-11-30 04:43:30 24 4
gpt4 key购买 nike

我有一个 holder 类 H,它有一个 unique_ptr 到类 A 的一个实例(HA 的所有者)。类 A 定义了一个嵌套类 B,并且有一个 unique_ptr 指向 B 的实例(A B 的所有者)。反过来,AB 实例应该更新其 A 的各个方面,因此 B 有一个原始的指向拥有它的 A 的指针。

我的问题是A的成员更新后,B无法准确返回。当创建 B 并创建其指向其所属 A 的指针时,其指针将超出范围。

当 holder 类不存在时,我可以让它工作(即 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 传递给 Bupdate_B() 函数来让代码工作,比如 update_B (A&a){ b_a = &a; } 但我不明白为什么上面的代码不起作用。

非常感谢您的任何见解。

最佳答案

您正被 A 的隐式移动构造函数所困扰。问题是这一行:

h_a = std::make_unique<A> (A(x, y));

这从给定的参数 A(x, y) 构造了一个指向 A 的唯一指针。 IOW,您正在从A已构建 实例构建A。第二个实例是从第一个实例移动构造的,因此接管了第一个 B 的实例,后者现在有一个指向其拥有实例的错误指针。

如果您修改代码以打印 AB 的身份,您就会看到这一点:

Creating instance of H
...creating instance of A (0x7ffecd5a6d40)...
:- Creating instance of B (0x7ffecd5a6cf0) within A (0x7ffecd5a6d40)...
:- ...B's y is set to 10
:- ...B belongs to an A with value 2
...A's x is set to 2
Updating A (0x19852a0)... A's x is now 3
Updating y of B (0x1985280) belonging to A (0x7ffecd5a6d40) with x value -849711776

如果我将您的代码更改为:

h_a = std::make_unique<A>(x, y);

...然后它按预期工作:

Creating instance of H
...creating instance of A (0x877280)...
:- Creating instance of B (0x7ffe479156c0) within A (0x877280)...
:- ...B's y is set to 10
:- ...B belongs to an A with value 2
...A's x is set to 2
Updating A (0x877280)... A's x is now 3
Updating y of B (0x8772a0) belonging to A (0x877280) with x value 3

但是,这不是完整的解决方案。您真正需要做的是为 A 提供一个移动构造函数来更新 B 的拥有实例以具有正确的指针,或者至少显式删除移动构造函数以便你不能不小心误用这个类。

关于c++ - 嵌套类的原始指针类成员无法返回分配的指向对象的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58239158/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com