面试题答案
一键面试- 构造函数自动调用顺序:
- 当创建
FinalClass
对象时,构造函数调用顺序遵循C++继承体系的规则。首先调用其直接基类(某个中间派生类模板)的构造函数,然后依次向上调用其基类的构造函数,最终调用BaseTemplate<T>
的构造函数。例如,如果FinalClass
继承自DeriveTemplate1<T>
,那么调用顺序为:BaseTemplate<T>
构造函数 ->DeriveTemplate1<T>
构造函数 ->FinalClass
构造函数。这是因为在创建一个对象时,需要先初始化其基类部分,再初始化自身部分。
- 当创建
- 利用模板元编程控制构造函数调用顺序:
- 方法一:使用特化模板
- 定义一个模板元编程类
InitSequence
,用于控制初始化操作。
template <typename T> struct InitSequence { static void init() { // 通用的初始化操作,如果有 } }; // 针对特定类型T的特化 template <> struct InitSequence<SpecificType> { static void init() { // 特定类型相关的初始化操作 } };
- 在
FinalClass
的构造函数中,在调用基类构造函数之前调用InitSequence<T>::init()
。
template <typename T> class FinalClass : public DeriveTemplate1<T> { public: FinalClass() { InitSequence<T>::init(); // 这里会先执行特定类型相关的初始化操作 // 然后基类构造函数会自动调用 } };
- 定义一个模板元编程类
- 方法二:使用模板参数包和折叠表达式(C++17及以后)
- 定义一系列初始化操作的函数。
template <typename T> void init1() { // 初始化操作1 } template <typename T> void init2() { // 初始化操作2 }
- 使用模板参数包和折叠表达式定义一个控制初始化顺序的模板。
template <typename T, typename... Args> void initSequence(Args... args) { (init1<T>(), init2<T>(),...); // 这里折叠表达式会按顺序执行init1和init2等操作 }
- 在
FinalClass
构造函数中调用initSequence
。
template <typename T> class FinalClass : public DeriveTemplate1<T> { public: FinalClass() { initSequence<T>(); // 执行特定类型相关的初始化操作 // 然后基类构造函数会自动调用 } };
- 方法一:使用特化模板