gpt4 book ai didi

c++ - 指向堆栈分配对象的指针和引用

转载 作者:太空宇宙 更新时间:2023-11-04 11:38:14 25 4
gpt4 key购买 nike

假设我有以下代码(它可能过于简单,但我认为这已经足够了):

struct BigObject {
A a;
B b;
};

struct A { ... };

struct B {
A const* a_ptr;
MyOtherClass someMethodUsingA() { ... }
}

class BigObjectBuilder {
BigObject build() {
BigObject o;
o.a = buildA();
o.b.a_ptr = &(o.a);

return o;
}
}

问题是 &(o.a) 以后可能指向任何东西,因为 o 的地址在返回时可能已经改变(调用移动或复制构造函数)。现在我发现大多数时候 &(o.a) 是相同的,所以调用 *(o.b.a_ptr) 不会导致段错误。 (我认为这是由于 RVO,因为那时 o 没有移动)。不管怎样,只要我不确定 o 的地址没有改变,这段代码就是不正确的。

一个明显的解决方案是要求动态分配我的 BigObject:

auto o_ptr = make_unique<BigObject>();

这个解决方案还不错(没有泄漏,并且解决了之前的问题。),但是我仍然觉得它不够优雅:我不需要动态分配,我只需要为我的 BigObject 指定一个固定地址。我认为这就是 Java 的做事方式。另一种解决方案是在 B 中使用拷贝,但 o.a 中的所有更改都不会影响 o.b.a,我不希望这样。

第三种解决方案是在 B 中没有 A 的拷贝、ptr 或引用,并在方法 B::someMethodUsingA() 的参数中传递 A。但是,在调用此函数时查找要传递的参数可能会很乏味。有时 B 类拥有指向 A 类的指针感觉更自然。

现在我发现这个问题在我的代码中一次又一次地发生:我想构建一个复杂的对象,子对象相互引用。根本问题是该对象不是“就地”创建的,它可能会在稍后的构建过程中移动(但不是在构建完所有内容之后)。

他们是否有任何已知的模式可以适用于此?我想这是一个很常见的问题,如果不是,那一定是因为我没有以正确的方式构建我的系统...

有没有办法确保某种 RVO ?我的意思是,由标准保证,而不是由编译器保证。像编译器警告说“BigObject”不能移动到不同的地址之类的东西”

我还想删除移动和复制构造函数和赋值运算符。但是我无法按值返回对象,即使实际上没有移动任何东西......

欢迎分享任何对您有用的东西!

最佳答案

我不明白为什么您需要结构对象及其在结构 BigObject 中的指针。你可以这样设计结构:

struct A { ... };
struct BigObject {
A a;
MyOtherClass someMethodUsingA() { /* Here you can use the variable a. */ }
};

如果你仍然想按照自己的方式编码,你可以为 struct BigObject 添加复制构造和分配构造函数,如下所示:

struct BigObject 
{
A a;
B b;

// copy-construct function
BigObject(const BigObject& old)
{
a = old.a;
b = old.b;
b.a_ptr = &a; // pay attetion
}

// assign construct function
BigObject& operator=(const BigObject& old)
{
if (this == &old) // avoid self-assignment
{
return *this;
}

a = old.a;
b = old.b;
b.a_ptr = &a;

return *this;
}
};

关于c++ - 指向堆栈分配对象的指针和引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22407383/

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