1.请设计一个类,该类只能在堆上创建对象
方法:将类的构造函数和拷贝构造函数声明为私有,防止别人调用拷贝在栈上生成对象
提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建
class heaponly
{
public:
static heaponly*getheap()
{
return new heaponly;
}
private:
heaponly() //构造私有
{}
heaponly(const heaponly&); //拷贝构造私有
};
int main()
{
heaponly* p1 = heaponly::getheap();
//heaponly p2;
//heaponly p3(*p1);
return 0;
}
2.设计一个类,该类只能在栈上创建对象
class stackonly
{
public:
static stackonly getonly()
{
stackonly obj;
return obj;
}
void print()
{
cout << "haha" << endl;
}
private:
stackonly() //构造函数私有,防止在外部用new创建对象
{} //拷贝构造就在栈上,所以拷贝构造不用私有
//stackonly(const stackonly&) = delete;
};
int main()
{
stackonly obj = stackonly::getonly();
obj.print();
//stackonly* p = new stackonly;
return 0;
}
另外还有一种方式,这种方式并不完全正确
方法:只要将new的功能屏蔽掉就可以,屏蔽operator new
class stack
{
public:
stack()
{}
private:
void* operator new(size_t size);
void operator delete(void* p);
};
//stack s3; 在数据段
int main()
{
stack s1;
//stack s2 = new stack;
return 0;
}
这段代码中 在全局区创建的S3对象,S3在数据段,并不在栈上。
单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的
全局访问点,该实例被所有程序模块共享
例如:在某个服务器程序中该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后
服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理
1.饿汉模式
就是说不管你用不用,程序启动时就创建一个唯一的实例对象
优点:简单明了,无需关注线程安全问题
缺点:如果在一个大环境下使用了过多的饿汉单例,则会生产出过多的实例对象,无论你是否要使用他们
class Singleton
{
public:
static Singleton* GetInstance()
{
return &m_instance;
}
private:
Singleton()
{};
Singleton(const Singleton&) = delete;
Singleton& operator=(Singleton const&);
static Singleton m_instance;
};
Singleton Singleton::m_instance;
int main()
{
Singleton *p1 = Singleton::GetInstance();
return 0;
}
懒汉模式:
如果单例对象构造十分耗时或者占用很多资源,比如加载插件,读取文件...有可能该对象程序运行时用不到
就要在程序一开始进行初始化,就会导致程序启动时非常缓慢,这种情况使用懒汉模式(延迟加载)更好
优点:延时加载,用的时候才会产生对象
缺点:需要保证同步,付出效率的代价。
class Singleton
{
public:
static Singleton* Getstance()
{
//加锁
if (m_pInstance == nullptr)
{
m_mtx.lock();
if (m_pInstance == nullptr)
{
m_pInstance = new Singleton;
}
m_mtx.unlock();
}
return m_pInstance;
}
//实现一个内嵌垃圾回收类
class CGarbo{
public:
~CGarbo(){
if (m_pInstance)
delete m_pInstance;
}
};
//定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象
static CGarbo Garbo;
private:
Singleton(){};
Singleton(const Singleton&) = delete;
Singleton&operator=(const Singleton&) = delete;
static Singleton* m_pInstance;
static mutex m_mtx;
};
Singleton* Singleton::m_pInstance = nullptr;//单例对象指针
mutex Singleton::m_mtx; //互斥锁
Singleton::CGarbo Garbo;