C++设计模式-Singleton----static+++++++const
来源:互联网 发布:药智网数据查询 编辑:程序博客网 时间:2024/06/17 15:53
#define _SINGLETON_H_
class Singleton
{
private:
//定义一个私有的静态全局变量来保存该类的唯一实例
static Singleton* pInstance;//静态成员,保存对象的唯一实例
/// 构造函数必须是私有的
/// 这样在外部便无法使用 new 来创建该类的实例
public:
/// 定义一个全局访问点
/// 设置为静态方法
/// 则在类的外部便无需实例化就可以调用该方法
//void Destroy();
static void Destroy();
};
#endif
===============================================================================================================
===============================================================================================================
#include "Singleton.h"
#include <iostream>
using namespace std;
Singleton* Singleton::pInstance = NULL;
Singleton::Singleton()
{
cout<< "Singleton..." << endl;
}
//尽管我两次访问了 GetInstance(),但是我访问的只是同一个实例,
Singleton* Singleton::Instance()
{
//这里可以保证只实例化一次
//即在第一次调用时实例化
//以后调用便不会再实例化
if(NULL == pInstance)
{
pInstance = new Singleton();
}
return pInstance;
}
void Singleton::Destroy()
{
delete pInstance;
pInstance = NULL;
cout<< "Destroy..." << endl;
}
==============================================================================================
=============================================================================================
#include "Singleton.h"
#include <iostream>
using namespace std;
int main()
{
Singleton* ps = Singleton::Instance();//通过全局访问点获取实例
Singleton::Destroy();
return 0;
}
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
class Singleton{ public: static Singleton* getInstance( ); ~Singleton( ); private: Singleton( ); static Singleton* instance;};
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000const和类
(1)const修饰成员变量
const修饰类的成员函数,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。
class A
{
…
const int nValue; //成员常量不能被修改
…
A(int x): nValue(x) { } ; //只能在初始化列表中赋值
}
(2)const修饰成员函数
const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰。
class A
{
…
void function()const; //常成员函数, 它不改变对象的成员变量.
//也不能调用类中任何非const成员函数。
}
对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。
a. const成员函数不被允许修改它所在对象的任何一个数据成员。
b. const成员函数能够访问对象的const成员,而其他成员函数不可以。
(3)const修饰类对象/对象指针/对象引用
· const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。
· const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。
例如:
class AAA
{
void func1();
void func2() const;
}
const AAA aObj;
aObj.func1(); ×
aObj.func2(); 正确
const AAA* aObj = new AAA();
aObj-> func1(); ×
aObj-> func2(); 正确
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
举了一些
C/C++
中用到
const
的地方。
1
,
const
变量
2
,
const
指针
3
,
const
引用
4
,
const
类
5
,类的
const
成员变量
6
,类的
const
成员函数
7
,
const
修饰函数的形参与返回值
下面我们分别讨论上面几种情况下,
const
的用法。
举了一些
C/C++
中用到
const
的地方。
1
,
const
变量
2
,
const
指针
3
,
const
引用
4
,
const
类
5
,类的
const
成员变量
6
,类的
const
成员函数
7
,
const
修饰函数的形参与返回值
下面我们分别讨论上面几种情况下,
const
的用法。
1,const变量
5,类的const成员变量
7,const修饰函数的形参与返回值
int a=10;
int &b=a;//声明b是a的引用,这样a的值变以后,b的值也变;b的值变以后,a的值也跟着变。
------------------------------------基础知识2int ival=1024;
int *pi=&ival; //pi指向一个int型的数
int **ppi=&pi; //ppi指向一个int型的指针
---------------------基础知识3
类的const数据成员
在类内部,const数据成员代表在对象的生命周期内该数据成员不可更改,也就是说这个const修饰的是该对象的一个数据,它是属于对象的,只有在该对象的有效期内起作用
2、类的static数据成员
在类内部,static数据成员代表了属于整个类的数据,并不属于单个对象,因此它在整个程序的运行过程中只有一个副本,不能在定义对象时对static成员进行初始化,就是不能用构造函数进行初始化。
------------------基础知识4
重载操作符的三个准则
1.右端值要为const 类型(不想改变他的值)Take a const-reference for the argument (the right-hand side of the assignment).
2.要返回一个引用,以便于实现(a=b=c…… (Do this by returning *this.)
3.检查是否为自我赋值Check for self-assignment, by comparing the pointers (this to &rhs).
------------------基础知识5C++中,若类的方法前加了static关键字,则该方法称为静态方法,反之为实例方法。静态方法为类所有,可以通过对象来使用,也可以通过类来使用。但一般提倡通过类名来使用,因为静态方法只要定义了类,不必建立类的实例就可使用。静态方法只能用类的静态成员。
const int ival = 1024;
int *&pi_ref = &ival; //错误,非const引用是非法的
const int *&pi_ref = &ival; //错误,需要临时变量,且引用的是指针,而pi_ref是一个非常量指针
const int * const &pi_ref = &ival; //正确
//补充
const int *p = &ival;
const int *&pi_ref = p; //正确
、、、、、、、、、、、、、、、、、、、、、、、、、、、、1.不允许非const引用指向需要临时对象的对象或值
int a = 2;
int &ref1 = a;// OK.有过渡变量。
const int &ref2 = 2;// OK.编译器产生临时变量,需要const引用
2.地址值是不可寻址的值
int * const &ref3 = &a; // OK;
3.于是,用const对象的地址来初始化一个指向指针的引用
const int b = 23;
const int *p = &b;
const int *& ref4 = p;
const int *const & ref5 = &b; //OK
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、下面我们分别讨论上面几种情况下,const的用法。
class S{ public: static S& getInstance() { static S instance; // Guaranteed to be destroyed. // Instantiated on first use. return instance; } private: S() {} // Constructor? (the {} brackets) are needed here. // C++ 03 // ======== // Dont forget to declare these two. You want to make sure they // are unacceptable otherwise you may accidentally get copies of // your singleton appearing.
//,拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。 S(S const&); // Don't Implement void operator=(S const&); // Don't implement//操作符重载 // C++ 11 // ======= // We can use the better technique of deleting the methods // we don't want. public: S(S const&) = delete; void operator=(S const&) = delete; // Note: Scott Meyers mentions in his Effective Modern // C++ book, that deleted functions should generally // be public as it results in better error messages // due to the compilers behavior to check accessibility // before deleted status};
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111private static Drawable sBackground;
@Override
protectedvoid onCreate(Bundle state){
super.onCreate(state);
TextView label =newTextView(this);
label.setText("Leaks are bad");
if(sBackground ==null){
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
上面几行代码,内存泄露挺严重的。sBackground是一个 static 变量,在 label调用setBackgroundDrawable的时候,会调用sBackground的setCallback,所以在sBackground中就存在label的引用。
而,label中又存在Activity的引用,所以此Activity一直不会被回收,即使已经finish了。
如何避免:
- 使用applicationContext作为上下文,避免使用activity
- 设置Drawable的Callback为null
- 在Service或者Activity使用内部类尽量使用static类。例如:使用Handler
关于第3点,看个例子:
1 static class IncomingHandlerextendsHandler { 2 private final WeakReference<UDPListenerActivity> mActivity; 3 4 IncomingHandler(UDPListenerActivity activity) { 5 mService = newWeakReference < UDPListenerActivity > (activity); 6 } 7 8 @Override 9 public void handleMessage(Message msg) {10 UDPListenerActivity activity = mActivity.get();11 if (activity != null) {12 activity.handleMessage(msg);13 }14 }15 }
很多地方我们需要使用到Context,比如我们自定义一个单例的CustomManager,当我们使用一些系统的服务时,就需要Context参数,这时如果使用Activity或者Service 作为context,就会容易造成内存泄露。
具体原因请看下面的这个例子:
当所持有的Context的引用是一个Activity或者Service,系统销毁它们后,由于CustomManager中有其静态的引用,所以Activity或者Service所占用的资源并不会被回收,造成内存泄露。
那么正确的方法是使用Application的context, 因为Application的context是单例的,并且它的生命周期属于整个应用进程。所以上边的代码需要改成:
- C++设计模式-Singleton----static+++++++const
- Singleton设计模式(C++)
- 设计模式-----Singleton模式
- 设计模式-Singleton模式
- 设计模式--Singleton模式
- 设计模式-------Singleton模式
- 设计模式--singleton模式
- 设计模式--Singleton模式
- 【设计模式】--SINGLETON模式
- 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)
- c++------virtual const static
- 探究 Singleton 设计模式
- 探究Singleton设计模式
- 设计模式之singleton
- 设计模式之Singleton
- [设计模式]Singleton
- 设计模式之singleton
- 设计模式之 Singleton
- IO多路复用的几种实现机制的分析
- 在Android Studio中NDK环境配置
- 第九周 项目3 两个稀疏矩阵的相加运算
- 基于C#的短信接口调用示例代码模板
- iOS调到各种权限设置收集
- C++设计模式-Singleton----static+++++++const
- 支持向量机学习笔记--原理篇(二)
- CXF访问WCF接口---一路填坑
- 总结->找工作[20]
- 【第九周项目3-稀疏矩阵的三元组表示的实现及应用(1)】
- Guid.NewGuid().ToString();
- 命令模式——参考《Head First设计模式》
- TCP、UDP、Socket区别
- 如何选择一家公司?