贵阳自助建站软件,一键生成,学校网站建设重要性,杭州协会网站建设文章目录 序言1. static静态成员2. C(伪)静态工具类3. 单例模式3.1 单例模式的特点3.2 单例模式的实现方式3.3 单例模式的缺点3.4 Meyer Singleton单例模式 4. (伪)静态工具类 vs 单例模式4.1 区别4.2 如何选择4.3 一些释疑 序言 比较C static#xff08;伪#xff09;静态(伪)静态工具类3. 单例模式3.1 单例模式的特点3.2 单例模式的实现方式3.3 单例模式的缺点3.4 Meyer Singleton单例模式 4. (伪)静态工具类 vs 单例模式4.1 区别4.2 如何选择4.3 一些释疑 序言 比较C static伪静态工具类和单例模式的异同方便工作中正确选用实现方式 说明Java/C#等高级语言支持静态类C不直接支持静态类的概念但是可以通过一些技巧来实现类似的功能仅包含静态成员 私有构造函数防止类实例化所以这里称其为伪静态类
1. static静态成员 说明2C静态成员和静态函数 (1) static修饰成员变量即为静态成员变量修改成员方法即为静态成员方法(2) 静态成员存储在全局变量区属于类本身不属于对象可通过类访问也可通过实例化后的对象访问因此静态成员不能在构造函数中初始化因为构造函数是用来构造单个对象的而静态成员属于类也不能用初始化列表来初始化(3) 静态成员在类外初始化时分配内存程序结束时释放等同于全局变量 静态局部变量作用域仅限于函数内部别的函数不能访问 静态全局变量作用域仅限于定义它的源文件而不是所有源文件(4) 静态成员变量在对象中不占用存储空间(5) 静态方法中只能访问静态成员变量和方法如果确实需要访问非静态成员应该通过函数传参方式 静态成员变量只是表面上遵守面向对象在类中可通过对象调用一定程度上破坏了面向对象因为没对象用类名也能直接调用静态成员静态变量可以看做类外的全局变量和全局函数被封装在了类内部与非静态变量和成员区别很大
2. C(伪)静态工具类 静态工具类 (1) class声明时使用static整个类是静态类(2) 静态类内部全是静态成员没有非静态成员(3) 静态类的成员不能有protected或protected internal访问保护修饰符可以有public、private限制符(4) 静态类不能被实例化因为不用实例化非静态成员C中私有构造函数可以防止类的实例化静态类存储在全局变量区生存周期和程序一致(5) 静态类的初始化在类外进行前面不加static以免与外部静态变量相混淆也不能使用this关键字因为已经实例化并开辟了内存初始化时不加访问限制符private、public等(6) 静态类不能包含构造函数但仍可声明静态构造函数以分配初始值或设置某个静态状态(7) 静态类不能指定任何接口实现不能有任何实例成员不能使用abstract或sealed修饰符(8) 静态类成员/函数通过类名::进行访问和调用不通过对象就可以调用(9) 静态类是密封的不能被继承不能拿来做父类 C中构造函数定义为private为什么能防止类的实例化 私有构造函数无法在类的外部被访问私有构造函数只能在类的内部被调用无法在类的外部被访问和调用。因此无法通过在类的外部实例化对象来创建类的实例 继承关系下的限制如果将构造函数定义为protected子类可以调用父类的protected构造函数来创建父类的实例。但是如果构造函数是private子类无法调用父类的private构造函数因此无法创建父类的实例 C伪静态类的实现
头文件 xxx.h
class MapUtil {
// 所有成员均为static
public:static const HdMap HdMap();static const PercepMap PercepMap();static const FusionMap FusionMap();private:static std::unique_ptrHdMap hdmap_;static std::mutex hdmap_mutex_;static std::unique_ptrPercepMap percep_map_;static std::mutex percep_map_mutex_;static std::unique_ptrFusionMap fusion_map_;static std::mutex fusion_map_mutex_;private: // 不能有protected访问修饰符MapUtil() delete; // 私有构造函数防止实例化静态成员不属于任何对象
};源文件 xxx.cc
// 不加static也不加访问限制符
std::unique_ptrHdMap MapUtil::hdmap_ nullptr;
std::mutex MapUtil ::hdmap_mutex_;const HdMap MapUtil::HdMap()
{std::lock_guardstd::mutex lock(hdmap_mutex_);if (hdmap_ ! nullptr) {return *(hdmap_.get()); // 不推荐这样使用
} else {hdmap_ CreateHdMap();
}
return *(hdmap_.get());
}3. 单例模式
单例模式设计模式中最基础最简单的一种也是C中常见的模式之一这里重点介绍Meyer单例
3.1 单例模式的特点
1 一个类只有一个实例2 该实例在运行周期内始终存在3 该实例可以被全局访问
3.2 单例模式的实现方式
1饿汉式单例模式 也称为静态单例模式程序运行之前就创建因此是线程安全的构造析构函数私有防止外部创建对象通过puclic getinstance访问 2懒汉式单例模式和双重检查锁懒汉式单例模式 在getInstance被调用时才会创建单例对象普通懒汉式单例模式线程不安全改进懒汉式单例模式加双重检查锁保证线程安全、避免资源浪费 3Meyer单例模式 利用C 11中local static变量的线程安全特性因此是线程安全的构造析构函数私有不能外部创建对象通过puclic getinstance访问在第一次调用时才创建单例类似懒汉模式此后每次获取都返回同一实例实例内静态局部变量在程序生命周期内只会被创建一次具有线程安全性不需加锁
3.3 单例模式的缺点
1单例模式的代码比较复杂可能需要在多线程环境下使用同步锁等机制以保证单例对象的唯一性和线程安全性2 单例对象在整个应用程序的生命周期内都存在于内存中可能会占用较多的系统资源特别是在单例对象比较庞大或需要长时间运行的情况下3单例模式在某种程度上违反了面向对象设计的一些原则例如开闭原则、依赖倒置原则等因为它将对象的创建和使用耦合在一起不太容易进行单元测试、模块化开发等单例模式在一些场景下非常有用但也不能滥用单例模式需要确保它是最优解决方案
3.4 Meyer Singleton单例模式
class Singleton
{
public:static Singleton Instance()
{/* 静态局部变量第一次调用时初始化全局生命周期 */static Singleton instance;return instance;}Singleton(const Singleton) delete;Singleton(Singleton) delete;Singleton operator(const Singleton) delete;Singleton operator(Singleton) delete;
private:Singleton() default;~Singleton() default;
};不暴露单例的构造析构函数保证单例类不会通过其他途径被实例化禁用单例类的拷贝构造、移动构造和赋值构造函数防止类的唯一实例被拷贝或移动
4. (伪)静态工具类 vs 单例模式
4.1 区别 1 实例 静态类没有实例所有成员都是静态的不需要实例化单例有唯一实例提供成员的访问接口 2 初始化 静态类在第一次加载时初始化静态类如懒汉模式可以延迟初始化 3 扩展性 静态类通常不能扩展单例类可以实现接口、继承或者其他使用方法扩展接口可覆写 4 全局访问 静态类通过类名直接访问成员单例类提供全局访问点以在整个程序中共享状态 5 访问效率 静态类被认为有更好的访问效率 6 可测试性 单例模式更容易测试 7 状态维护 单例模式更方便于维护状态如果不需要维护任何状态则适合用静态类在一些框架中单例对象更好管理 8 面向对象 单例模式比静态类更加面向对象单例可以使用继承和多态继承基类实现自己的接口提供不同的功能返回不同的实现对象
4.2 如何选择
1 静态类适合一些工具类xxx_Util如地图类MapUtil()2 如果单例不维护任何状态与实例对象无关不考虑继承和多态只提供全局访问适合用静态类3 从线程安全、性能、兼容性上来看也是选用实例化方法为宜
4.3 一些释疑
1 静态类常驻内存单例对象不是所以静态效率高但占内存类似空间换时间 不是。首次加载后都常驻内存都放在method table中效率区别很小静态类并没有很高效 2 静态类在堆上分配内存单例在栈上分配内存 不是。静态成员存储在全局变量区单例类的对象都有自己的存储区域普通成员变量存储在栈区 3 单例要先创建再使用静态类直接使用所以静态类更简单 不是。单例的引入是为了更模式化、更面向对象化单例和静态类的区分是为了解决模式问题如“人类”和单个人。如果确实需要使用实例那创建实例对象就是必须的没有麻烦简单一说如何选择见5.2所示 【参考文章】 [1]. C静态类实现 [2]. C中的静态成员 [3]. C静态成员和静态类 [4]. C静态成员和静态类推荐 [5]. C静态类 [6]. C单例模式 [7]. C单例模式介绍推荐 [8]. 静态变量 [9]. Meyer单例 [10]. Meyer单例推荐 [11]. 静态类vs单例模式 [12]. 静态类vs单例模式推荐 [13]. 静态类 vs单例模式
created by shuaixio, 2024.02.18