更改智能指针对象并在之后访问它
Changing a smart pointers object and accessing it afterwards
我目前正在重新设计我最近编写的一个相当复杂的程序。该程序由相互依赖的各种对象组成。我现在想要实现的是更改其中一个对象并将其替换为相同类型但不同属性的对象的功能(例如,在构建新对象期间分配的属性)。
实现此功能的正确方法是什么?
到目前为止我做了什么?
目前我正在使用一个 "master class" 包含一组 unique_ptr 包含不同的对象。假设 object1 依赖于 object2,所以在构造过程中我通过引用 object1 的构造函数传递包含 object2 的智能指针。
由于我希望能够在构造后访问 object2 的函数,因此我需要以某种方式引用它以备后用:
根据我的理解,我不能使用指向底层对象的原始指针,因为它指向某个内存地址,当旧对象被替换时该地址可能会发生变化。
目前我正在尝试使用引用,它引用智能指针本身,它不应该改变它的地址,但应该始终知道 object2 所在的位置。
这是一个选择吗?因为现在我正在 运行 解决我曾经在 object2 中有指向某些变量的指针的问题(主要是为了更容易编写和阅读代码),但是我很确定我会 运行再次出现相同的地址问题。在这种情况下,我是否应该在我的第一个引用中使用对变量的引用 - 这是否有效?
我也可以使用引用智能指针的原始指针,但感觉这不是正确的方法。我不久前开始使用 C++,我觉得我可能过度使用了指针,或者也许我没有正确使用智能指针,我不知道 - 所以任何帮助将不胜感激!
假设所有权是唯一的(所以没有 shared_ptr
),这样您的 MasterClass
并且只有 MasterClass
拥有子对象的所有实例,您需要做的是使用 unique_ptr
并通过 const
左值引用传递它们,这样您就可以始终访问特定子对象的正确地址(因为 unique_ptr
也可以用作包装器).
我的意思是这样的:
class Object2 {
const std::unique_ptr<Object1>& object1;
public:
Object2(const std::unique_ptr<Object1>& object1) : object1(object1) { }
}
class MasterClass {
std::unique_ptr<Object1> object1;
std::unique_ptr<Object2> object2;
MasterClass() : object1(new Object1()), object2(new Object2(object1)) { }
void replace() {
// no problem for Object2
object1.reset(new Object1());
}
}
请注意,如果您需要从 class 而非 MasterClass
更改托管对象,您可以使用非 const
引用,但这暴露了一些问题,因为 std::unique_ptr
由非 const 引用传递并不能真正向您保证被调用的函数不会通过移动到它自己的 unique_ptr
或诸如此类微妙的东西来获得所有权。
我目前正在重新设计我最近编写的一个相当复杂的程序。该程序由相互依赖的各种对象组成。我现在想要实现的是更改其中一个对象并将其替换为相同类型但不同属性的对象的功能(例如,在构建新对象期间分配的属性)。
实现此功能的正确方法是什么?
到目前为止我做了什么?
目前我正在使用一个 "master class" 包含一组 unique_ptr 包含不同的对象。假设 object1 依赖于 object2,所以在构造过程中我通过引用 object1 的构造函数传递包含 object2 的智能指针。
由于我希望能够在构造后访问 object2 的函数,因此我需要以某种方式引用它以备后用:
根据我的理解,我不能使用指向底层对象的原始指针,因为它指向某个内存地址,当旧对象被替换时该地址可能会发生变化。 目前我正在尝试使用引用,它引用智能指针本身,它不应该改变它的地址,但应该始终知道 object2 所在的位置。
这是一个选择吗?因为现在我正在 运行 解决我曾经在 object2 中有指向某些变量的指针的问题(主要是为了更容易编写和阅读代码),但是我很确定我会 运行再次出现相同的地址问题。在这种情况下,我是否应该在我的第一个引用中使用对变量的引用 - 这是否有效?
我也可以使用引用智能指针的原始指针,但感觉这不是正确的方法。我不久前开始使用 C++,我觉得我可能过度使用了指针,或者也许我没有正确使用智能指针,我不知道 - 所以任何帮助将不胜感激!
假设所有权是唯一的(所以没有 shared_ptr
),这样您的 MasterClass
并且只有 MasterClass
拥有子对象的所有实例,您需要做的是使用 unique_ptr
并通过 const
左值引用传递它们,这样您就可以始终访问特定子对象的正确地址(因为 unique_ptr
也可以用作包装器).
我的意思是这样的:
class Object2 {
const std::unique_ptr<Object1>& object1;
public:
Object2(const std::unique_ptr<Object1>& object1) : object1(object1) { }
}
class MasterClass {
std::unique_ptr<Object1> object1;
std::unique_ptr<Object2> object2;
MasterClass() : object1(new Object1()), object2(new Object2(object1)) { }
void replace() {
// no problem for Object2
object1.reset(new Object1());
}
}
请注意,如果您需要从 class 而非 MasterClass
更改托管对象,您可以使用非 const
引用,但这暴露了一些问题,因为 std::unique_ptr
由非 const 引用传递并不能真正向您保证被调用的函数不会通过移动到它自己的 unique_ptr
或诸如此类微妙的东西来获得所有权。