C++ C++;CRTP初始化
我在运行以下程序时遇到了一个错误C++ C++;CRTP初始化,c++,initialization,crtp,C++,Initialization,Crtp,我在运行以下程序时遇到了一个错误 #include <iostream> #include <vector> template <typename Derived> struct CRTPBase { CRTPBase() { func(); } void func() { static_cast<Derived*>(this)->_func(); } }; struct CRTPChild : CRTPBa
#include <iostream>
#include <vector>
template <typename Derived>
struct CRTPBase {
CRTPBase() {
func();
}
void func() {
static_cast<Derived*>(this)->_func();
}
};
struct CRTPChild : CRTPBase<CRTPChild>{
using CRTPBase<CRTPChild>::CRTPBase;
void _func(){
vec.resize(10);
vec[0] = 2;
}
std::vector<int> vec;
};
int main()
{
CRTPChild obj;
std::cout << obj.vec[0] << std::endl;
}
#包括
#包括
模板
结构CRTPBase{
CRTPBase(){
func();
}
void func(){
静态_cast(this)->_func();
}
};
结构CRTPChild:CRTPBase{
使用CRTPBase::CRTPBase;
void _func(){
向量调整(10);
vec[0]=2;
}
std::vec;
};
int main()
{
CRTPChild obj;
std::cout基类将在子类之前初始化(即构造)。这意味着当您调用CRTPChild::func
时,对象的CRTPChild
部分(包括向量)尚未构造。以任何方式使用向量都将导致错误
不要访问基类构造函数中子类的(非静态)成员。调用CRTPBase
构造函数时,CRTPChild
尚未完全构造,因此调用其成员函数是未定义的行为
未定义行为的表现方式取决于平台、编译器和月球阶段
特别是,当您的成员是int时,当您使用int时,它尚未构造的事实不会导致程序崩溃-int
没有不变量。另一方面,Vector有不变量,因此访问未构造的向量将违反这些不变量,并导致不正确的内存访问。您的代码没有定义行为。问题来自;对于派生类CRTPChild
,首先调用基类CRTPBase
的构造函数,然后初始化CRTPChild
的数据成员vec
。调用\u func
时(从基类的构造函数)vec
根本没有初始化
2) 然后,按从左到右的顺序初始化直接基类,如下所示
它们出现在此类的基本说明符列表中
3) 然后,按照以下顺序初始化非静态数据成员:
类定义中的声明
将类型更改为
int
它仍然是。UB意味着任何事情都是可能的,它可能会导致segfault,也可能不会。为什么在构造向量之前要尝试使用向量?基类的构造函数在派生类的构造函数之前运行,派生类的构造函数反过来调用vec的构造函数。因此,vec尚未构造当你开始使用它的时候,它就被反作用了。