单例的弊端回顾以下单例模式的定义保证一个类仅有一个实例并提供一个该实例的全局访问点。这里提到了「全局 」两个字可见单例本质就是一种全局资源。那自然无法避免全局对象的各种弊端如滥用问题任何人都可以使用该资源生命周期问题该对象从构造起贯穿整个应用程序种缺乏灵活性全局资源的修改将涉及直接使用和间接使用的全部模块测试的困难使用全局资源点不方便进行单元测试单例的避免其实解决的方法有不少这里展示注入的方式对取消单例。怎么注入呢通常可以通过对象的构造函数或者 set 方法将原先的单例对象注入到目标对象中。单例的方式class MySql { public: static MySql instance() { static MySql s_instance; return s_instance; } public: void foo() {} private: MySql() default; ~MySql() default; private: MySql(const MySql) delete; MySql operator(const MySql) delete; }; // 依赖于单例 class Widget { private: MySql* sql; public: Widget() { sql MySql::instance(); } void refresh() { sql-foo(); // TODO } }; int main() { Widget widget; widget.refresh(); // TODO }注入的方式class MySql { public: MySql() default; ~MySql() default; public: void foo() {} }; // 完全独立的模块 class Widget { private: MySql* sql; public: Widget(MySql* sql) : sql(sql) { } void refresh() { sql-foo(); // TODO } }; int main() { MySql sql; // 通过构造器进行注入 Widget widget(sql); widget.refresh(); // TODO }