目录
1. 请设计一个类,只能在堆上创建对象
2. 请设计一个类,只能在栈上创建对象
3.请设计一个类,不能被继承
4.请设计一个类,只能创建一个对象(单例模式)
饿汉模式
懒汉模式
1. 请设计一个类,只能在堆上创建对象
第一种(不推荐):
class OnlyHeap
{
public:
void DestoryObj()
{
delete this;
}
private:
~OnlyHeap()
{
cout << "~OnlyHeap()" << endl;
}
private:
int _a;
};
int main()
{
OnlyHeap* ptr = new OnlyHeap;
ptr->DestoryObj();
return 0;
}
第二种(推荐):?
class OnlyHeap
{
public:
//2.提供一个静态的公有函数创建对象,对象创建的都在堆上
static OnlyHeap* CreateObj()
{
return new OnlyHeap;
}
private:
//1.构造函数私有化
OnlyHeap()
:_a(0)
{}
private:
int _a;
//C++98 防拷贝------只声明,不实现,声明为私有
OnlyHeap(const OnlyHeap& oh);
};
int main()
{
//static突破类域
OnlyHeap* ptr = OnlyHeap::CreateObj();
OnlyHeap copy(*ptr);//报错
delete ptr;
return 0;
}
2. 请设计一个类,只能在栈上创建对象
第一种:
class StackOnly
{
public:
static StackOnly CreateObj()
{
return StackOnly();
}
private:
StackOnly()
:_a(0)
{}
private:
int _a;
};
int main()
{
StackOnly so = StackOnly::CreateObj();
return 0;
}
第二种:?
class StackOnly
{
public:
StackOnly()
:_a(0)
{}
private:
//重载一个类专属operator new
//C++98 防调用---只声明,不实现,声明为私有
void* operator new(size_t size);
void operator delete(void* ptr);
//C++11
void* operator new(size_t size) = delete;
void operator delete(void* ptr) = delete;
private:
int _a;
};
int main()
{
StackOnly so;
StackOnly* ptr = new StackOnly;//报错
//这种方式存在一些漏洞,无法禁止在静态区创建对象
static StackOnly sso;
return 0;
}
3.请设计一个类,不能被继承
class NonInherit
{
public:
static NonInherit GetInstance()
{
return NonInherit();
}
private:
NonInherit()
{}
};
//C++98这种方式不够直接
//这里是可以继承的,但是Derive不能创建对象,因为Derive的构造函数
//必须调用父类NonInherit构造,但是NonInherit的构造函数私有了
//私有在子类中不可见,这里的继承不会报错,而继承的子类创建对象会报错
class Derive :NonInherit
{};
int main()
{
return 0;
}
4.请设计一个类,只能创建一个对象(单例模式)
饿汉模式
?缺陷:单例对象时main函数之前创建初始化的
1,如果单例对象的构造函数中要做很多工作,可能会导致程序启动慢
2,如果多个单例类,并且他们之间有依赖关系,那么饿汉模式无法保证
懒汉模式
第一个调用GetInstance时,才会创建初始化单例对象
相对于饿汉,不存在可能会导致启动慢的问题,并且可以控制顺序依赖问题
?双检查加锁:
Singleton* Singleton::_sinst;//定义
mutex Singleton::_mtx;
Singleton& Singleton::GetInstance()
{
//双检查加锁
if (_sinst == nullptr)
{
_mtx.lock();
if (_sinst == nullptr)
{
_sinst = new Singleton;
}
_mtx.unlock();
}
return *_sinst;
}
|