成员变量在每个方法中有不同的地址
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
构造函数尚未完成。这会导致未定义的行为。
我有这段代码(最小示例):
#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
构造函数尚未完成。这会导致未定义的行为。