gpt4 book ai didi

c++ - 为具有相互引用/循环依赖的类复制构造函数

转载 作者:行者123 更新时间:2023-11-30 05:47:17 28 4
gpt4 key购买 nike

所以我有一个我认为是涉及对象的非常常见的 C++ 问题作品。问题域是这样的:动画 gif 可以有很多框架,绘制框架取决于 Gif 的其他上下文帧。

所以我有这个模型(对于这个问题已经大大简化了,但应该说明):

class Gif {
std::vector<Frame> _frames;

// Makes Frame objects from file and puts them in _frames
Gif(const char* file){...};

// For clarity, works and copies the _frames member
Gif(const Gif& other) = default;
};

class Frame {
Frame(...){
// Make a frame object
}
void draw(const Gif& context){
// draws self considering context's other frames
}
};

这可行,但为了简单起见并避免在中绘制 Frame错误的上下文,我希望 draw 方法不会采用那个 context 参数。所以我想用 const 创建框架引用成员 _context:

class Frame {
const Gif& _context;

// Make a frame object
Frame(const Gif& context) _context(context){...}

// Explicit default copy-constructor, for clarity. Breaks horribly
// when called from Gif's copy constructor, since the new Frame will
// reference the wrong context, which might be deleted.
Frame(const& Frame other) = default;


void draw(){
// draws self considering _context's other frames
}
};

这可以编译,但在复制 Gif 时会严重中断。 框架Gif 的对象是拷贝,但它们引用了错误的上下文,通常已被删除。

我认为 const 引用成员对于您打算复制的对象...我应该使用指针和在自定义 Gif 的复制构造函数的主体中为新的 Frame 显式重置它?

如果有,是什么类型指针(原始/智能)?难道没有一个好的 C++11 技术来制作这是“自动”发生的?

或者我应该打破循环依赖以及如何打破?

编辑(感谢 KillianDS):为了清楚起见,您从 gif1 开始使用一些指向 gif1 的帧(frame1_1、frame1_2、...),现在您想要使用复制的帧(frame2_1、frame2_2)将 gif1 复制到 gif2 ,...) 但这指向 gif2 吗?

最佳答案

基本上你想让复制的帧指向复制的gif。这不适用于两个级别的默认复制构造函数,因为您不会盲目复制对象。您的 Gif 复制构造函数可能需要变成如下所示:

class Gif {
std::vector<Frame> _frames;

Gif(const Gif& other) : some_var(other.some_var), _frames(other.frames) ...
{
for(auto& frame: _frames)
{
frame.update_context(this);
}
}
};

现在的问题是,在 Frame 类中,您使用的是无法重新放置的引用,因此您无法更新它们。如果您的用例很简单,通常您可以使用裸指针:

class Frame {
const Gif* _context;

// Make a frame object
Frame(const Gif* context) _context(context){...}

Frame(const& Frame other) = default;
void update_context(const Gif* context) { _context = context; }
};

为什么是裸指针而不是智能指针:

  1. Frame没有理由对Gif进行内存管理,只是引用。
  2. 您似乎不太可能拥有没有 Gif 上下文的框架。但即使在这种情况下,帧开始时没有 gif,您也可以只使用 std::nullptr
  3. 您想避免使用智能指针,因为您的框架指向您的 gif,而您的 gif“指向”您的框架,而您的框架指向...

当点 2 不再正确时,您应该何时考虑将其设为智能指针(在本例中为 std::weak_ptr)。如果帧以 gif 开头并且 gif 在某处丢失,但帧没有丢失,则使用 weak_ptr 更容易,您可以在其中实际检查 gif 上下文是否仍然存在。对于裸指针,您应该始终将指针指向 nullptr,否则更容易出错。

关于c++ - 为具有相互引用/循环依赖的类复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28628959/

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