这是代码:
#include <iostream>
struct Parent
{
virtual ~Parent() = default;
};
class Buddy
{
public:
virtual ~Buddy() = default;
Buddy(Parent& p) : parent_ { p } {}
bool IsHovered() const { return is_hovered_; }
private:
bool is_hovered_ = false;
Parent& parent_;
};
class Child : public Parent, public Buddy
{
public:
Child() : Buddy { *this } {}
bool BuddyIsHovered() const { return IsHovered(); }
};
int main()
{
Child c;
// Expected 'false', but 'true' is always printed.
std::cout << std::boolalpha << c.BuddyIsHovered() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我可以假设问题(可能是未定义的行为)是由于Childand的多重继承和相互使用而发生的Buddy。从另一个角度来看,我也有这样的假设:
Child;分配内存Child构造函数;在我看来,编译器应该知道所有 3 个类的正确地址;Parent, Buddy, Child。所以,当Childconstructor_运行时,Buddy内存已经被初始化,因此Buddy可以使用。我的意思是,Child的代码可以使用 的Buddy代码,它不会触及 的未初始化数据成员Buddy。我的哪些假设是正确的,哪些是错误的?
Hol*_*Cat 19
似乎发生的是 MSVC 解释
Child() : Buddy { *this } {}
Run Code Online (Sandbox Code Playgroud)
作为
Child() : Buddy { static_cast<Buddy &>(*this) } {}
Run Code Online (Sandbox Code Playgroud)
它调用 的复制构造函数Buddy。它会parent_自行初始化,这会导致未定义的行为(由于在其生命周期开始之前读取它,该生命周期在初始化完成时开始)。
修复方法是显式转换为Parent &:
Child() : Buddy { static_cast<Parent &>(*this) } {}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
784 次 |
| 最近记录: |