【发布时间】:2021-10-14 08:22:59
【问题描述】:
我正在研究一些代码,它似乎可以工作,但我不确定它是否是已定义的行为。
我认为其中存在问题,因为 Base 是通过对 Derived 成员变量的引用构造的 - 在我的理解中,这是在 Base 之后构造的。
我对此进行了一些研究,我发现的所有答案都表明 Base 是在 Derived 之前构造的,并且来自 Derived 构造函数的参数可以转发给 Base 构造函数。
但是派生成员呢,它们可以安全地转发给基础构造函数吗? Base 中的构造函数和析构函数甚至成员函数是否可以处理无效对象?
这里是有问题的简单代码示例:
class Base
{
public:
Base(SomeClass & obj): m_obj(obj)
{
// Does using m_obj here cause problems with a Derived instance?
}
virtual ~Base()
{
// Does using m_obj here cause problems with a Derived instance?
}
void SomeMethod()
{
// Does using m_obj here cause problems with a Derived instance?
}
private:
SomeClass & m_obj;
};
class Derived : public Base
{
public:
Derived():Base(m_derObj){}
private:
SomeClass m_derObj{123};
};
也许我错过了 C++ 提供的一些保证 - 或者我们只是幸运,错误从未发生过。
【问题讨论】:
-
除了
SomeClass m_derObj(123);中的错误(这是一个无效的成员函数声明),没关系。 -
很抱歉 - 修复它并添加到 OnlineGDB 的链接,它可以编译。感谢您的快速回答,但也许您可以帮我弄清楚为什么这不是问题,对我来说,在 Base-Constructor 运行之后似乎仍然构造了 SomeClass。
-
@Someprogrammerdude 当引用
Base::m_obj被初始化的时候,被引用的对象Derived::m_derObj还没有被初始化,对吧?是否可以创建对尚未初始化的对象(基本上是其存储)的引用? -
@DanielLangr 它尚未初始化,但它存在并且可以创建对它的引用。只要该对象不以任何其他方式使用,那么一切都很好。
-
@mile4712
Base构造函数可以初始化m_obj成员,但是构造函数体不能使用引用的对象,因为它没有被初始化。
标签: c++ oop undefined-behavior