gpt4 book ai didi

c++ - C++中的相互类引用

转载 作者:行者123 更新时间:2023-11-30 03:19:38 27 4
gpt4 key购买 nike

我公司有一些代码采用以下形式:

class ObjectA {
public:
ObjectA(ObjectB &objectB): objectB(objectB) { }

void Initialize() { ... }

private:
ObjectB &objectB;
};

class ObjectB {
public:
ObjectB(ObjectA &objectA): objectA(objectA) { }

void Initialize() { ... }

private:
ObjectA &objectA;
};

基本上,两个类相互依赖。

这本身并不是困扰我的问题,(虽然这不是 IMO 的出色设计)在这两种情况下,相互依赖性都是通过引用通过构造函数传递的.

因此,实际构造这对对象的唯一方法(它们在应用程序中都是必需的) 是传递一个不完整的引用作为依赖项。为了解决这个问题,将单独的 Initialize 方法添加为第二阶段构造函数,然后在创建两个对象后调用该构造函数。因此,构造函数通常除了将构造函数参数分配给对象内部并在 Intizialize 方法中初始化所有内容外什么都不做。

虽然代码可能是有效的,但我倾向于认为这是一个有根本缺陷的设计,原因如下:

  1. 不能保证依赖对象的状态 build 者
  2. 它要求开发人员额外调用Initialize
  3. 它排除了使用检查成员变量是否已初始化的编译器警告
  4. 没有什么可以阻止 Initialize 被多次调用,这可能会导致奇怪的、难以追踪的错误

我的同事告诉我,使用单独的初始化方法可以简化对象构造,因为开发人员不必担心在应用程序根目录中声明了哪些顺序对象。它们可以以完全任意的顺序声明和构造,因为一旦调用 Initialize 一切都保证有效。

我一直主张对象构造应该遵循依赖关系图的相同顺序,并且应该重新设计这些对象以消除相互依赖,但我想看看 SO 专家对此有何评论。我认为这是不好的做法是错误的吗?

编辑:

这些类实际构建的方式是通过如下所示的工厂类:

Factory {
public:
Factory():
objectA(objectB),
objectB(objectA) {
}
private:
ObjectA objectA;
ObjectB objectB;
};

最佳答案

是的,这是不好的做法。传递对 objectB 的引用以供 objectA 使用,但它尚未正确初始化,这是一个禁忌。

它现在可能是符合标准且安全的代码,因为 ObjectA 不会尝试在其构造函数中访问传递给 ObjectB 的引用,但安全性被线程挂起.如果稍后有人决定只在构造函数中初始化或访问 objectB 中的任何内容,或以任何其他方式更改它以使用 objectB,您最终会得到 UB。

这听起来像是在两个构造函数都运行后重新设置指针的用例。

关于c++ - C++中的相互类引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53575098/

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