关于设计类的问题,什么电脑适合设计类时候适合用Shared类

版权声明:本文为博主原创文章,未经博主允许不得转载。 /qq_/article/details/

之前已经实现了一个,为什么还要再论智能指针呢?
(1)指针生命周期结束时主动释放堆空间;
(2)一片堆空间最多只能由一个指针标识;
(3)杜绝指针运算和指针比较。

如何实现 SharedPointer 使得多个智能指针对象可以指向同一片堆内存 , 同时支持堆内存的自动释放?
Pointer继承自Object,只要不实现析构函数,那么Pointer这个类就是一个抽象类。实现方式:

通过计数机制ref标识堆内存:
1、堆内存被指向时 : ref++;
2、指针被置空时 :ref –;
3、ref==0时 :释放堆内存。
(1)实现拷贝构造时,自身的m_ref要挂接到被拷贝的对象上去;
(2)实现赋值操作时,说明不再指向原来的堆空间,自身的m_ref要减减,为空时要释放指针指向的空间和计数机制的空间;
(3)析构函数里要调用clear函数实现堆空间内存自动释放。
核心是下面的clear函数的实现,同时要注意保证程序的异常安全。

(1)SharedPointer最大程度的模拟了原生指针的行为;
(2)计数机制确保多个智能指针合法的指向同一片堆空间;
(3)智能指针只能用于指向堆空间中的内存;
(4)不同类型的智能指针不要混合使用;
(5)堆对象的生命周期由智能指针进行管理。

}

在开发中经常会用到单例设计模式,目的就是为了在程序的整个生命周期内,只会创建一个类的实例对象,而且只要程序不被杀死,该实例对象就不会被释放。下面我们来看看单例的概念、用途、如何创建,以便加深理解。

  • 在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在APP开发中我们可能在任何地方都要使用用户的信息,那么可以在登录的时候就把用户信息存放在一个文件里面,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。
  • 有的情况下,某个类可能只能有一个实例。比如说你写了一个类用来播放音乐,那么不管任何时候只能有一个该类的实例来播放声音。再比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,这里就可以通过单例模式来避免两个打印任务同时输出到打印机中,即在整个的打印过程中我只有一个打印程序的实例。

有两种方法来创建单例,下面分别介绍

1、GCD方式创建单例

上面两种方式都可以创建单例,而且保证了用户不管是通过shareInstance方法,还是alloc、copy方法得到的实例都是一样的。

上面代码的关键之处就在于如何在多线程情况下保证创建的单例还是同一个。

我们先看看在GCD情况下,如果不使用dispatch_once和同步锁创建单例会出现什么问题,去掉两者后创建单例的代码如下

nil还是成立的,那么线程2又会创建一个_instace。

此时就创建了两个实例对象,导致问题。

dispatch_once保证程序在运行过程中只会被运行一次,那么假设此时线程1先执行shareInstance方法,创建了一个实例对象,线程2就不会再去执行dispatch_once的代码了。从而保证了只会创建一个实例对象。

解决办法2、使用互斥锁

假设此时线程1在执行shareInstance方法,那么synchronize大括号内创建单例的代码,如下所示:

就会被当做一个任务被加上了一把锁。此时假设线程2也想执行shareInstance方法创建单例,但是看到了线程1加的互斥锁,就会进入睡眠模式。等到线程1执行完毕,才会被唤醒,然后去执行上面所示的创建单例的代码,但是此时_instance !=nil,所以不会再创建新的实例对象了。从而保证只会创建一个实例对象。

但是互斥锁会影响性能,所以最好还是使用GCD方式创建单例。


如果我们需要在程序中创建多个单例,那么需要在每个类中都写上一次上述代码,非常繁琐。

我们可以使用宏来封装单例的创建,这样任何类需要创建单例,只需要一行代码就搞定了。

/p/4
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

}

我要回帖

更多关于 什么电脑适合设计类 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信