做网站建设的公司是什么类型,微商城怎么推广,设计制作售卖,免费推广的平台目录 设计一个类#xff0c;不能被拷贝
设计一个类#xff0c;只能在堆上创建对象
设计一个类#xff0c;只能在栈上创建对象
设计一个类#xff0c;无法被继承
设计一个类#xff0c;只能创建一个对象(单例模式)
饿汉模式
懒汉模式 设计一个类#xff0c;不能被拷…
目录 设计一个类不能被拷贝
设计一个类只能在堆上创建对象
设计一个类只能在栈上创建对象
设计一个类无法被继承
设计一个类只能创建一个对象(单例模式)
饿汉模式
懒汉模式 设计一个类不能被拷贝
这个很简单利用C11新特性中的关键字delete给到拷贝构造与赋值重载即可~
class BanCopy
{//...BanCopy(const BanCopy) delete;BanCopy operator(const BanCopy) delete;//...
};
设计一个类只能在堆上创建对象
既然是要在堆上创建对象那么首先要做的就是确保该对象是new出来的而非是由构造函数生成的~
class HeapOnly
{
public://禁止赋值重载HeapOnly operator(const HeapOnly) delete;//禁止拷贝构造HeapOnly(const HeapOnly) delete;
private://构造私有化//无参HeapOnly(){}//有参HeapOnly(int x, int y):_x(x),_y(y){}int _x;int _y;
};int main()
{HeapOnly ho1;HeapOnly* ho2 new HeapOnly;return 0;
}
不过这样new的时候也无法调用构造了所以我们再包装一层~ 不过还是遇到问题OBJ是创建对象用的但调用OBJ得是对象调用那么我们就不要让它作为成员函数而是超脱其作用域~
然后再把默认的拷贝函数与赋值重载禁掉防止在栈上拷贝对象~
class HeapOnly
{
public:templateclass... Argsstatic HeapOnly* CreateObject(Args... args){return new HeapOnly(args...);}/*static HeapOnly* CreateObject(){return new HeapOnly;}*///禁止赋值重载HeapOnly operator(const HeapOnly) delete;//禁止拷贝构造HeapOnly(const HeapOnly) delete;
private://构造私有化//无参HeapOnly(){}//有参HeapOnly(int x, int y):_x(x),_y(y){}int _x 1;int _y 2;
};int main()
{/*HeapOnly ho1;HeapOnly* ho2 new HeapOnly;*/HeapOnly* ho2 HeapOnly::CreateObject();HeapOnly* ho3 HeapOnly::CreateObject(3,4);//禁止拷贝//HeapOnly copy(*ho2);return 0;
}
ps:可搭配上前面所学的可变参数模板使用~
设计一个类只能在栈上创建对象
只能在栈上的话思路和前面差不多先把构造给私有化由我们来控制在那开辟对象再把new给禁止掉防止在堆上开辟~
class StackOnly
{
public:templateclass... Argsstatic StackOnly CreateObj(Args... args){return StackOnly(args...);}// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉void* operator new(size_t size) delete;void operator delete(void* p) delete;
private:StackOnly():_a(0){}
private:int _a;int _b;
};int main()
{StackOnly so1 StackOnly::CreateObj();StackOnly so2 StackOnly::CreateObj(3,4);//无法使用StackOnly* ptr3 new StackOnly(obj);return 0;
}
设计一个类无法被继承
class A final
{//...
};
直接用C11新特性的关键字final即可~
设计一个类只能创建一个对象(单例模式) 一个类只能创建一个对象即单例模式该模式可以保证系统中该类只有一个实例并提供一个 访问它的全局访问点该实例被所有程序模块共享 。 饿汉模式 饿汉一开始(main之前)就创建出对象。就是说不管你将来用不用程序启动时就创建一个唯一的实例对象。 想让一些数据当前程序只有一份那就可以把这些数据放到这个类里面再把这个类设计成单例这个数据就只有一份了 namespace hunger
{class Singleton{public://利用静态成员函数拿到静态成员static Singleton* GetInstance(){return _sint;}void Print(){cout _x endl;cout _y endl;}//禁止拷贝构造与赋值重载防止其他对象生成Singleton(Singleton const) delete;Singleton operator(Singleton const) delete;private://构造函数私有防止构造其他对象Singleton(int x,int y):_x(x), _y(y){}int _x;int _y;// 静态成员对象不存在对象中存在静态区相当于全局的定义在类中受类域限制// 这才符合在main之前创建对象static Singleton _sint;};//静态成员声明成员类型成员所处內域Singleton Singleton::_sint(1, 1);
}
int main()
{//直接调静态函数拿到对象hunger::Singleton::GetInstance()-Print();
}
ps:之所以拿指针而非对象一个是安全问题指针销毁方便~但我感觉无论用指针还是引用返回都差不多~ 不过饿汉模式有两个问题存在 如果单例对象数据较多构造初始化成本较高那么会影响程序启动的速度。迟迟进不了main函数多个单例类有初始化启动依赖关系饿汉无法控制。假设A和B两个单例假设要求A先初始化B再初始化饿汉无法保证 懒汉模式 懒汉优点第一次使用实例对象时创建对象。进程启动无负载。多个单例实例启动顺序自由控 制。 如果单例对象构造十分耗时或者占用很多资源比如加载插件啊初始化网络连接啊读取 文件啊等等而有可能该对象程序运行时不会用到那么也要在程序一开始就进行初始化 就会导致程序启动时非常的缓慢。所以这种情况使用懒汉模式 延迟加载 更好。 //在饿汉模式基础上进行改造
namespace lazy
{class Singleton{public://利用静态成员函数拿到静态成员static Singleton* GetInstance(){// 第一次调用时创建单例对象// 线程安全问题需要加锁if (_psint nullptr){_psint new Singleton;}return _psint;}static void DelInstance(){if (_psint){delete _psint;_psint nullptr;}}void Print(){cout _x endl;cout _y endl;}//禁止拷贝构造与赋值重载防止其他对象生成Singleton(Singleton const) delete;Singleton operator(Singleton const) delete;private://构造函数私有防止构造其他对象Singleton(int x 0,int y0):_x(x), _y(y){}~Singleton(){cout ~Singleton() endl;}int _x;int _y;// 静态成员对象不存在对象中存在静态区相当于全局的定义在类中受类域限制static Singleton* _psint;// 内部类class GC{public:~GC(){Singleton::DelInstance();}};// 定义一个静态成员变量程序结束时系统会自动调用它的析构函数从而释放单例对象static GC gc;};Singleton* Singleton::_psint nullptr;Singleton::GC Singleton::gc;
}
int main()
{//直接调静态函数拿到对象lazy::Singleton::GetInstance()-Print();return 0;
} 在懒汉模式中我们最开始是构建出一个对象指针只有在第一次被调用的时候才会创建对象这样可以减少初始化时的开销~由于静态成员变量是指针那就需要写对应的析构函数及时释放其资源如果我们不想手动释放也可以学一下构建内部类的方式让其自动调用对指针的析构函数~
如果不想用GC内部类析构对象指针也可以这样写
namespace lazy
{class Singleton{public://利用静态成员函数拿到静态成员static Singleton* GetInstance(){// 第一次调用时创建单例对象// 线程安全问题需要加锁//局部静态对象在第一次调用该函数时才初始化static Singleton _sint;return _sint;}static void DelInstance(){if (_psint){delete _psint;_psint nullptr;}}void Print(){cout _x endl;cout _y endl;}//禁止拷贝构造与赋值重载防止其他对象生成Singleton(Singleton const) delete;Singleton operator(Singleton const) delete;private://构造函数私有防止构造其他对象Singleton(int x 0, int y 0):_x(x), _y(y){}~Singleton(){cout ~Singleton() endl;}int _x;int _y;// 静态成员对象不存在对象中存在静态区相当于全局的定义在类中受类域限制static Singleton* _psint;};Singleton* Singleton::_psint nullptr;
}int main()
{//直接调静态函数拿到对象lazy::Singleton::GetInstance()-Print();return 0;
}
不用new而是直接创建对象~
总结在main之前初始化就是饿汉在main中第一次调用就是懒汉~