类的三种特殊设计【每日一题】
来源:互联网 发布:淘宝店铺上传不了图片 编辑:程序博客网 时间:2024/05/18 02:53
1.设计一个类不能被继承 。
解法一、将该类的构造函数设为私有函数
在C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数,要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数,那么当一个类试图从它那继承的时候,必然会由于调用构造函数、析构函数而导致编译错误。那么既然这个类的构造和析构函数都是私有的,我们就必须通过定义公有的静态函数来创建和释放类的实例。
class FinalClass1 { public : static FinalClass1* GetInstance() { return new FinalClass1; } static void DeleteInstance( FinalClass1* pInstance) { delete pInstance; pInstance = 0; } private : FinalClass1() {} ~FinalClass1() {} };
这个类不能被继承,而且只能得到堆上的实例,得不到栈上的实例。
解法二、虚拟继承
template <typename T> class MakeClass { friend T;private: MakeClass(){} ~MakeClass(){}};class FinalClass2{public: FinalClass2(){} ~FinalClass2(){}};
2.设计一个类只能在堆上创建对象。
分配堆区域内的对象属于动态建立类对象过程。
编译器对他们的内存分配是在运行时动态分配的,使用new运算符将对象建立在堆空间中。这个过程分为两步:
第一步,执行operator new()函数,在对中搜索合适的内存并进行分配;
第二步,调用构造函数构造对象,初始化这片内存空间。使用这种方法,间接调用类的构造函数。
那么怎样设计一个类能够只在堆上创建对象呢?
很容易就想到的一个方法是把类的构造函数声明为私有,就无法在类的外部调用类的构造函数建立对象,只能使用new运算符来建立对象。前面已经说过,new运算符的执行过程分为两步,C++提供new运算符的重载其实只是允许重载operator new()函数,不能重载new运算符,而operator new()函数只用于分配内存,无法提供构造函数,所以,我们再定义一个GetObj函数,用于在堆上new对象,通过GetObj函数,建立的对象都是在堆上的new出来的,将函数声明为静态的,就可以通过域作用访问符访问GetObj函数,在堆上建立对象。(在C++中静态成员函数也是类函数,及这个函数不属于某个具体的对象,而是属于一个类的,这个类实例化的每个成员都可用,同时,这个类也可以直接调用这个函数而不用实例化一个对象。)
class BB { public: static BB& GetObj(int b1 = 0,int b2 = 0) { return *(new BB(b1,b2)); } private: BB(int b1 = 0,int b2 = 0) :_b1(b1) ,_b2(b2) {} int _b1; int _b2; }; void Test() { BB b = BB::GetObj(); }
3.设计一个类只能在栈上创建对象。
分配在栈区域内的对象属于静态建立类对象过程。
编译器对它们的内存分配是在编译阶段就完成的,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。
那么怎样设计一个类能够只在栈上创建对象呢?
只有使用new运算符,对象才会建立在堆上,所以只要禁用new运算符就可以实现类对象只能建立在栈上,将operator new()设为私有就可以了,一定要记得,重载了new就要重载delete
class CC { public: CC() {} ~CC() {} private: void* operator new(size_t)//重载operator new() ,这里函数返回值和参数都是固定的 {} void operator delete(void* ptr)//也要重载operator delete() {} };
- 类的三种特殊设计【每日一题】
- 每日一题(三)
- JAVA自学之每日一题(三)
- 每日一题 No.38 AI贪吃蛇(三)
- 每日一题(46) - 不能被继承的类
- 每日一题(54) - 扑克牌的顺序
- 每日一题(66) - 字符串的排列
- 每日一题 - 剩下的数字?
- 每日一题31:图的遍历
- oracle 每日一题-游标的参数
- 每日一题之栈的实现
- 每日一题--最小的k个数
- 每日一题--二叉树的深度
- 每日一题--扑克牌的顺子
- Linux的三种特殊权限
- 循环“停止”的三种特殊语句
- 《每日编程》----《设计模式》----《三》----bridge模式
- 每日一题2
- 暑假写题第七天
- Quartz之CronTrigger
- 卫星照片
- Eclipse 设置项目集
- 小M开发_JQuery_day0714
- 类的三种特殊设计【每日一题】
- 网络安全(Web-safe)字体
- 我们的看板实践
- Uva455-Periodic Strings-周期串
- JSONP解决跨域请求问题
- TensorFlow学习笔记(4)——深层神经网络
- hdu 3038 How Many Answers Are Wrong (带权并查集)
- 二维数组中的查找
- 2017.7.10日C组模拟赛总结