面试题答案
一键面试#include <iostream>
// 模板类 TemplateClass 定义
template<typename T1, typename T2>
class TemplateClass {
public:
// 默认构造函数
TemplateClass() {
std::cout << "TemplateClass 默认构造函数被调用" << std::endl;
}
// 接受一个类型为 T1 的构造函数
TemplateClass(const T1& value1) : data1(value1) {
std::cout << "TemplateClass 接受一个 T1 类型参数的构造函数被调用" << std::endl;
}
// 接受两个不同类型参数的构造函数
TemplateClass(const T1& value1, const T2& value2) : data1(value1), data2(value2) {
std::cout << "TemplateClass 接受一个 T1 和一个 T2 类型参数的构造函数被调用" << std::endl;
}
protected:
T1 data1;
T2 data2;
};
// 模板子类 SubTemplateClass 定义
template<typename T1, typename T2>
class SubTemplateClass : public TemplateClass<T1, T2> {
public:
// 默认构造函数
SubTemplateClass() {
std::cout << "SubTemplateClass 默认构造函数被调用" << std::endl;
}
// 接受一个类型为 T1 的构造函数
SubTemplateClass(const T1& value1) : TemplateClass<T1, T2>(value1) {
std::cout << "SubTemplateClass 接受一个 T1 类型参数的构造函数被调用" << std::endl;
}
// 接受两个不同类型参数的构造函数
SubTemplateClass(const T1& value1, const T2& value2) : TemplateClass<T1, T2>(value1, value2) {
std::cout << "SubTemplateClass 接受一个 T1 和一个 T2 类型参数的构造函数被调用" << std::endl;
}
};
int main() {
// 使用不同模板参数实例化 SubTemplateClass 并创建对象
SubTemplateClass<int, double> obj1;
SubTemplateClass<int, double> obj2(10);
SubTemplateClass<int, double> obj3(10, 3.14);
return 0;
}
构造函数重载情况及调用顺序
obj1
的创建:- 首先调用
TemplateClass<int, double>
的默认构造函数,因为SubTemplateClass
的默认构造函数会隐式调用父类的默认构造函数。 - 然后调用
SubTemplateClass<int, double>
的默认构造函数。 - 输出:
TemplateClass 默认构造函数被调用 SubTemplateClass 默认构造函数被调用
- 首先调用
obj2
的创建:- 调用
TemplateClass<int, double>
的接受一个int
类型参数的构造函数,因为SubTemplateClass
的接受一个int
类型参数的构造函数显式调用了父类相应的构造函数。 - 然后调用
SubTemplateClass<int, double>
的接受一个int
类型参数的构造函数。 - 输出:
TemplateClass 接受一个 T1 类型参数的构造函数被调用 SubTemplateClass 接受一个 T1 类型参数的构造函数被调用
- 调用
obj3
的创建:- 调用
TemplateClass<int, double>
的接受一个int
和一个double
类型参数的构造函数,因为SubTemplateClass
的接受一个int
和一个double
类型参数的构造函数显式调用了父类相应的构造函数。 - 然后调用
SubTemplateClass<int, double>
的接受一个int
和一个double
类型参数的构造函数。 - 输出:
TemplateClass 接受一个 T1 和一个 T2 类型参数的构造函数被调用 SubTemplateClass 接受一个 T1 和一个 T2 类型参数的构造函数被调用
- 调用
模板实例化对构造函数调用顺序的影响
在上述代码中,模板实例化在编译时发生。编译器根据 main
函数中使用的具体类型(如 int
和 double
)生成相应的 TemplateClass
和 SubTemplateClass
类的实例。构造函数的调用顺序遵循类继承体系中的规则,即先调用父类的构造函数,再调用子类的构造函数。模板实例化本身并不改变构造函数的调用顺序,只是根据实际类型生成相应的类定义及构造函数定义,使得在运行时能正确执行构造函数。