类--设计一个类不能被继承&&设计一个类只能在堆上创建对象&&设计一个类只能在栈上创建对象。
来源:互联网 发布:mysql恢复删除的数据 编辑:程序博客网 时间:2024/06/06 01:25
1.设计一个类不能被继承
解法一:将构造函数设为私有函数
在C++中,子类的构造函数会自动调用父类的构造函数,子类的析构函数也会调用父类的析构函数。要想一个类不能被继承,只要把它的构造函数和析构函数都设置为私有函数。那么当一个类试图从那里继承时,势必会因为调用构造函数和析构函数而导致编译错误。
可是这个类型的构造函数和析构函数都是私有函数,我们怎样才能得到该类型的实例呢?我们可以通过定义共有的静态函数来创建和释放实例。
class SealedClass1 { public: static SealedClass1*GetInstance() { return new SealedClass1(); } static void DeleteInstance(SealedClass1*pInstance) { delete pInstance; } private: SealedClass1() {}; ~SealedClass1() {}; };
解法二:利用虚拟继承
template<class T> class MakeSealed { friend T; private: MakeSealed(); ~MakeSealed(); }; class SealedClass2:virtual public MakeSealed<SealedClass2> { public: SealedClass2(); ~SealedClass2(); };
这里尽管类MakeSealed<.SealedClass2>的构造函数和析构函数都是私有的,但是由于类SeaLedClass2是它的友元函数,因此在SeaLedClass2中调用MakeSealed<.SealedClass2>的构造函数和析构函数不会出现编译错误。
但是,当我们再试图从SeaLedClass2中继承一个类并创建它的实例的时候,却不能通过编译。比如:
class Ttr:public SealedClass2{ public: Try() {} ~Try() {}};
这里由于类SeaLedClass2是从MakeSealed<.SealedClass2>继承过来的,在调用Try的构造函数时,会跳SealedClass2直接调用MakeSealed<.SealedClass2>的构造函数。但是Try不是MakeSealed<.SealedClass2>的友元函数,所以会出现错误。
PS:
第二种方法可移植性不好,虽然SealedClass2在VS中能够编译,但是在GCC中还不支持模板参数类型作为友元类型。
2.设计一个类只能在堆上创建对象
就是不能静态的建立对象,即不能直接调用类的构造函数。
分析:
(1)容易想到将构造函数设为私有,在构造函数私有之后,无法在类外部调用构造函数来构造类对象,只能使用new运算符来建立对象,然而,前面已经说过,new运算符的执行过程分为两步,c++提供new运算符的重载,其实是只提供operator new() 函数,而operator()函数是进行内存分配的,无法提供构造功能,因此这种方法是不可以的
(2)对象建立在栈上面时,是由编译器分配空间的,调用构造函数来构造栈对象,当对象使用完之后,编译器会调用析构函数来释放栈对象所占的空间,编译器管理了对象的整个生命周期,编译器为对象分配空间的时候,只要是非静态的函数都会检查,包括析构函数,但是此时析构函数不可访问,编译器无法调用类的析构函数来释放内存,那么编译器将无法在栈上为对象分配内存
因此,将析构函数设为私有,类对象就无法建立在栈上了。
class a{ public : a(){} void destory(){ delete this; } private: ~a(){};};
那可以尝试使用a b来建立对象,编译报错,提示析构函数无法访问,这样就只能使用new来创建对象,构造函数是共有的,可以直接调用,但是类中必须通过destory()函数来进行内存的释放,类对象使用完之后,必须调用destory()函数
上述方法两个缺点:(1)无法解决继承问题,因为通常情况之下a作为基类,一般析构函数要设为vitual,然后子类重写,已实现多态,因此析构函数不能设为private,不过c++还有protected访问控制方式,将析构函数设置为protected,这样子类可以访问,但是类外无法访问。
(2)使用不方便,不统一,因为你使用了new创造了对象,但是不能使用delete释放对象,必须使用destory函数,这种方式比较怪异,所以我们也可以将构造函数设置为protected,同时提供另一public static create()函数来进行替代new。这样 create()创建对象在堆上,destory()释放内存。
3.只能建立在栈上
只有使用new操作符,才会使对象建立在堆上,因此只要禁用new操作符就可以了,所以我们将operator new()操作符设为保护或者私有就可以了
class a{ public : a(){}; ~a(){}; protected: void* operator new(size_t t){}; //重载new,注意参数以及返回值 void operator delete(void *ptr){}; //重载了new,就要重载delete };
- 设计一个类不能被继承;只能在堆上创建对象;只能在栈上创建对象
- 类--设计一个类不能被继承&&设计一个类只能在堆上创建对象&&设计一个类只能在栈上创建对象。
- -设计一个类不能被继承 2.设计一个类只能在堆上创建对象。 3.设计一个类只能在栈上创建对象。
- 1.设计一个类不能被继承 2.设计一个类只能在堆上创建对象。 3.设计一个类只能在栈上创建对象
- 设计一个类不能被继承 2.设计一个类只能在堆上创建对象。 3.设计一个类只能在栈上创建对象
- C++:1.设计一个类不能被继承 2.设计一个类只能在堆上创建对象。 3.设计一个类只能在栈上创建对象。
- 1.设计一个类不能被继承 2.设计一个类只能在堆上创建对象。 3.设计一个类只能在栈上创建对象
- 根据类(不能被继承、只能在栈上/堆上创建对象)的特点设计一个类
- 设计类不能被继承 、只能在堆上创建对象、只能在栈上创建对象。
- 链表带环问题/设计一个类不能被继承/设计一个类只能在堆(栈)上创建对象
- 设计一个类只能在堆(栈)上创建
- 创建一个不能被继承的类和只能在堆上(或栈上)创建对象
- 每日一刷——一个类不能被继承 &类只能在堆上创建对象&类只能在栈上创建对象。
- C++创建一个类(1.只能在堆上创建; 2 只能在栈上创建; 3 不能被继承(堆上和栈上都可以创建))
- C++创建一个类(1.只能在堆上创建; 2 只能在栈上创建; 3 不能被继承(堆上和栈上都可以创建))
- 定义一个只能在堆上生成对象的类&&定义一个只能在栈上生成对象的类&&定义一个类不能被继承
- 让一个类只能在对上创建对象或者只能在栈上实例化
- 设计只能在堆或者栈上创建的类
- 百度陆奇内部最新演讲:成为优秀工程师的五个方法
- python核心高级学习总结2----------pdb的调试
- JAVA中集合类对比表
- HDU
- iOS直播之搭建Linux直播RTMP服务器
- 类--设计一个类不能被继承&&设计一个类只能在堆上创建对象&&设计一个类只能在栈上创建对象。
- hdu 1495
- CSS选择器3
- 再聊tcp keepalive机制和与之相关的tcp RST
- 跨域请求XDM
- Linux下查看和添加PATH环境变量
- 理解Android Binder机制:驱动篇
- DLL导出
- Linux Signal handling(信号处理)Arm64