成员变量在每个方法中有不同的地址

Member variable has different addresses in each method

我有这段代码(最小示例):

#include <iostream>
#include <memory>

class Base {
public:
    virtual void test() = 0;

    virtual ~Base() = default;
};

template <typename T>
class Derived : public Base {
public:
    Derived() {
        foo();  // foo() gets called
    }

    void test() override {
        std::cout << "Derived test" << std::endl;
    }

    void foo() {
        static_cast<T&>(*this).bar(); // call method from child
    }
};

class Final : public Derived<Final> {
public:
    void test() override {
        std::cout << "Final::test(): " << &var << std::endl;
    }

    void bar() {
        std::cout << "Final::bar(): " <<  &var << std::endl;
    }

    int var;

};

int main() {
    std::unique_ptr<Base> a = std::make_unique<Final>(Final());
    a->test();

    return 0;
}

问题来了。变量var实际上在方法Final::test()Final::bar()上是不同的。从代码 abode 的输出中可以明显看出这一点:

Final::bar(): 0x7ffee5ad3988
Final::test(): 0x7fb8dbc017b8

我相信这是由于继承和虚拟调度引起的,但我不明白为什么会这样。请问你能帮帮我吗? 如果你能帮我想出一种方法来摆脱 CRTP 并且只坚持继承,我也会很感激 - 现在我不能,因为我需要从 Derived.[=16= 的构造函数调用虚拟方法]

I can't figure out why this happens. Could you help me please?

这只是另一个未定义的行为

当您使用语句 std::make_unique<Final>(...) 构造 Final 对象时,将调用构造函数的层次结构(以正确的顺序)。

Final::Final() calls Derived::Derived()

但是,Derived 的构造函数调用 foo(),它执行强制转换并调用 bar()。 调用 bar() 时, Final 构造函数尚未完成。这会导致未定义的行为。