面试题答案
一键面试原理
- 全局变量初始化顺序:在C++中,全局变量的初始化顺序是未定义的。如果两个全局变量相互依赖,不加以控制可能会导致一个变量在依赖它的变量初始化之前被使用,从而引发未定义行为。
- 静态局部变量:静态局部变量在首次进入其所在函数时初始化,其初始化顺序由其在代码中首次使用的顺序决定,这可以用来控制初始化顺序。
实现方式
- 使用函数返回静态局部变量:
在这个例子中,#include <iostream> class B { public: B() { std::cout << "B initialized" << std::endl; } }; class A { public: A(const B& b) : b_(b) { std::cout << "A initialized" << std::endl; } void print() const { std::cout << "A depends on B" << std::endl; } private: const B& b_; }; const B& getB() { static B b; return b; } const A& getA() { static A a(getB()); return a; } int main() { getA().print(); return 0; }
getA
函数依赖于getB
函数返回的B
对象,由于静态局部变量的特性,getB
中的b
会在getA
中的a
之前初始化,从而确保A
在初始化时B
已经初始化完成。 - 使用单例模式:
这里通过单例模式确保#include <iostream> class B { public: static B& getInstance() { static B instance; return instance; } B() { std::cout << "B initialized" << std::endl; } private: B() = default; B(const B&) = delete; B& operator=(const B&) = delete; }; class A { public: static A& getInstance() { static A instance; return instance; } A() : b_(B::getInstance()) { std::cout << "A initialized" << std::endl; } void print() const { std::cout << "A depends on B" << std::endl; } private: B& b_; A() = default; A(const A&) = delete; A& operator=(const A&) = delete; }; int main() { A::getInstance().print(); return 0; }
B
的实例在A
的实例之前被初始化,因为A
的实例化依赖于B
的实例。单例模式中的静态成员变量保证了其唯一性和特定的初始化顺序。