我很难调试生产中的崩溃。只是想与这里的人们确认语义。我们有一堂课,比如...
class Test {
public:
Test()
{
// members initialized ...
m_str = m_str;
}
~Test() {}
private:
// other members ...
std::string m_str;
};
有人更改了初始化以使用 ctor 初始化列表,这在我们的代码语义中是相当正确的。除其他事项外,初始化的顺序及其初始值是正确的。所以这个班级看起来像......
class Test {
public:
Test()
: /*other inits ,,, */ m_str(m_str)
{
}
~Test() {}
private:
// other members ...
std::string m_str;
};
但代码突然开始崩溃!我将一长串单元与这段代码隔离开来m_str(m_str)
。我通过以下方式确认了这一点链接文本.
难道一定要崩溃吗?标准对此有何规定? (这是未定义的行为吗?)
第一个构造函数相当于
Test()
: m_str()
{
// members initialized ...
m_str = m_str;
}
也就是说,当您在构造函数中进行赋值时,m_str
已经被隐式初始化到一个空字符串。因此,对 self 的分配虽然完全没有意义且多余,但不会造成任何问题(因为std::string::operator=()
正如任何编写良好的赋值运算符应该检查自赋值并且在这种情况下不执行任何操作)。
但是,在第二个构造函数中,您试图初始化m_str
其自身位于初始值设定项列表中 - 此时它尚未初始化。所以结果是未定义的行为。
Update:对于原始类型,这仍然是未定义的行为(导致字段具有垃圾值),但它不会崩溃(通常 - 请参阅下面的注释以了解异常),因为原始类型根据定义没有构造函数、析构函数,并且不包含指向其他类型的指针对象。
对于任何不包含具有所有权语义的指针成员的类型也是如此。std::string
特此证明不是其中之一:-)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)