gpt4 book ai didi

c++ - 为什么这段代码编译时没有提示构造函数?

转载 作者:搜寻专家 更新时间:2023-10-31 01:30:57 24 4
gpt4 key购买 nike

前一段时间我用一组嵌套类编写了一些代码。今天看了一下,我想知道为什么在我实例化一个 C 类型的对象时它会编译。

我的困惑是这样的。 B 有一个私有(private)构造函数。这个构造函数的实现负责A的构造,但是A的构造需要B的实例,感觉是先有鸡还是先有蛋的场景。 B 的构造需要 A 的构造,A 又需要 B 的构造,如此等等,无穷无尽。

我有以下类 - 直接剥离以演示问题:

// ******* A ******** //
class A {
public:
A(A& _Parent, int id);
private:
A& Parent;
};

inline A::A(A& _Parent, int id)
: Parent(_Parent)
{
}


// ******* B ******** //
class B:public A {
public:
static B& GetInstance();
private:
B();
};

inline B::B()
: A(B::GetInstance(), 0)
{
}

inline B& B::GetInstance()
{
static B b;
return b;
}


// ******* C ******** //
class C:public A {
public:
C();
};

inline C::C()
: A(B::GetInstance(), 0)
{
}

最佳答案

缩小问题范围:

inline B& B::GetInstance()
{
static B b;
return b;
}

inline B::B()
: A(B::GetInstance(), 0)
{
}

static B b; 行在第一次调用函数时创建了一个 B 对象。然而,b的构造随后调用了GetInstance,到达了static B b;行,而b仍然是 build 中。

这种情况由 C++14 [stmt.dcl]/4 涵盖:

[...] such a variable is considered initialized upon the completion of its initialization. [...] If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.

我删除了一个部分,讨论如果抛出异常会发生什么,或者如果两个不同的线程同时尝试初始化静态变量。该标准确实允许在第一次调用函数之前初始化局部静态变量,但即使实现这样做了,也会出现同样的问题,即控件以递归方式重新输入声明。


作为未定义的行为,任何事情都可能发生。一种可能的结果是它似乎按预期工作。该标准不要求在编译时对此进行诊断——这是一件很难分析的事情。如评论中所示,一个版本的 gcc 在运行时检测到这一点并抛出异常。也许您的原始编译器通过使用一个标志来指示执行是否已到达该行来实现局部静态,并在调用构造函数之前设置该标志。

标准中具有未定义行为的基本原理是避免对实现实现明确定义行为的方式施加约束(在这种情况下,确保局部静态的方法仅初始化一次)。

当然,您应该找到解决问题的方法,因为未定义的行为将来可能会以难以预测的方式以不同的方式表现出来。

关于c++ - 为什么这段代码编译时没有提示构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46700013/

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