MST

星途 面试题库

面试题:C++复杂模板类中对象成员初始化顺序及优化

假设有如下模板类结构: ```cpp template <typename T> class Outer { public: T innerObj1; std::vector<T> innerVec; Outer(const T& val1, const std::vector<T>& vec) : innerVec(vec), innerObj1(val1) {} }; class ComplexType { public: int data1; double data2; ComplexType(int d1, double d2) : data1(d1), data2(d2) {} }; ``` 当创建 `Outer<ComplexType>` 对象时,分析 `innerObj1` 和 `innerVec` 中元素的初始化顺序。如果希望优化初始化性能,尤其是在 `ComplexType` 构造开销较大时,你会如何调整代码结构或初始化方式?
23.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

初始化顺序

在创建 Outer<ComplexType> 对象时,innerObj1innerVec 中元素的初始化顺序如下:

  1. 首先,按照类中成员变量声明的顺序进行初始化。所以 innerObj1 会先被初始化。
  2. 接着,innerVec 中的元素会按照 vec 中元素的顺序被初始化。

优化初始化性能

ComplexType 构造开销较大时,可以考虑以下几种优化方式:

  1. 使用移动语义:如果 ComplexType 支持移动构造函数,可以在 Outer 的构造函数中使用 std::move 来避免不必要的拷贝。例如:
template <typename T>
class Outer {
public:
    T innerObj1;
    std::vector<T> innerVec;
    Outer(T&& val1, std::vector<T>&& vec) : innerVec(std::move(vec)), innerObj1(std::move(val1)) {}
};
  1. 减少构造次数:如果可能,尽量在构造 Outer 对象之前,预先构造好 ComplexType 对象,避免在 std::vector 初始化过程中频繁构造。
  2. 使用 emplace_back:在构造 innerVec 时,使用 emplace_back 代替 push_backemplace_back 会直接在 vector 中构造对象,避免额外的拷贝或移动。例如:
template <typename T>
class Outer {
public:
    T innerObj1;
    std::vector<T> innerVec;
    Outer(const T& val1, const std::vector<T>& vec) : innerObj1(val1) {
        for (const auto& v : vec) {
            innerVec.emplace_back(v);
        }
    }
};
  1. 考虑使用 std::vector 的 reserve 方法:在添加元素到 innerVec 之前,使用 reserve 方法预先分配足够的空间,减少动态内存分配的次数。例如:
template <typename T>
class Outer {
public:
    T innerObj1;
    std::vector<T> innerVec;
    Outer(const T& val1, const std::vector<T>& vec) : innerObj1(val1) {
        innerVec.reserve(vec.size());
        for (const auto& v : vec) {
            innerVec.emplace_back(v);
        }
    }
};