C++中如何定义不能被继承的类
来源:互联网 发布:miui msa是什么软件 编辑:程序博客网 时间:2024/06/06 11:46
学习过Java和c#的童鞋应该都知道,在Java中定义了关键字final表示一个类不能被继承,在C#中也有相同意义的关键字sealed表示一个类不能被继承,那仫在C++中呢?在C++11之前是没有的类似这样的关键字的,只能自己实现了。(在C++11中该关键字已经被加入到C++中,这个关键字的作用就是阻止类的进一步派生和虚函数的进一步重载)。
如何在C++中定义一个不能被继承的类呢?
想法一:私有构造函数来解决
我们都知道在C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。如果想要一个类无法被继承,那仫这个类的构造函数和析构函数必须是私有的,但是这样又会出现新的问题?就是这个类的构造函数和析构函数是私有的,我们如何获取和删除这个类的实例化对象呢?共有的静态函数就可以解决这个问题。
class Base{public: //编写静态函数来创建和释放类的实例化 static Base *GetSpace() { cout<<"GetSpace()"<<endl; return new Base(); } static void DeleteSpace(Base *del) { cout<<"DeleteSpace()"<<endl; delete del; }private: //私有化构造和析构函数 Base() {} ~Base() {}};int main(){ //静态成员函数没有隐含this指针参数,使用类型::作用域访问符直接调用静态成员函数 Base *b=Base::GetSpace(); Base::DeleteSpace(b); system("pause"); return 0;}
这样的实现会不会存在什仫问题呢?通过观察上面的代码我发现实例化一个对象只能使用new来实例,也就是说这个新创建的对象只能在堆上生成,这就存在一定的局限性。那仫如何解决呢?
想法二:利用虚拟继承的方法
同样是将父类的构造函数私有化,但是却定义了一个模板类型的友元,因为友元的特性:如果一个类是另一个类的友元,友元类的每个成员函数都是另一个类的友元函数,都可访问另一个类中的保护或私有数据成员。我们在子类中调用父类的构造和析构函数是不会出错的。
这种想法比方法一的想法好的一点就是:既可以在堆上实例化对象也可以在栈上实例化对象。
template<typename T>class Base{ friend T; //定义友元,子类可以访问父类的私有成员对象private: Base() { cout<<"Base()"<<endl; } ~Base() { cout<<"~Base()"<<endl; }};//虚继承class Sub:virtual public Base<Sub> {public: Sub() { cout<<"Sub()"<<endl; } ~Sub() { cout<<"~Sub()"<<endl; }};int main(){ Sub s1; //可以在栈上开辟 Sub *s2=new Sub; //可以在堆上开辟 delete s2; system("pause"); return 0;}
如果此时对Sub进行继承并对继承Sub的类进行实例化的时候是无法编译通过的。因为Sub是虚拟继承,所以当调用Test的构造函数的时候,会跳过Sub而直接调用Base的构造函数,又因为Base的构造函数是私有的且Test并不是Base的友元所以是不能调用的。
所以Sub就是满足题意的不能被继承的类。
class Test:public Sub{public: Test() { cout<<"Test()"<<endl; } ~Test() { cout<<"~Test()"<<endl; }};
当然了在C++中定义不能被继承的类有许多其他的方法,在这里我就只介绍这两种啦!!!
- C++中如何定义不能被继承的类
- 如何定义一个不能被继承的类
- 如何定义一个不能被继承的类
- C++中定义一个不能被继承的类
- C++定义不能被继承的类
- C++定义不能被继承的类
- 定义一个不能被继承的类
- c++中如何实现一个不能被继承的类
- 不能被继承的类[C/C++/C#]
- Java中不能被继承的类
- C++中如何让一个类不能被继承
- C++中如何使类不能被继承
- C++中如何使类不能继承
- C++中如何使类不能继承
- C++中如何使类不能继承
- C++中如何使类不能继承
- C++中如何使类不能继承
- 【中科大洋笔试题】定义一个不能被继承的类,并且只能实例化3个对象。
- SVN的具体使用过程2【资料+操作+截图】客户端
- 老板的骗局
- F
- java内存区域与内存溢出异常
- 夜读丨努力奋斗的过程中,你常会掉进这三个思维陷阱
- C++中如何定义不能被继承的类
- 文件名 目录名或卷标语法不正确
- Java开发中的23种设计模式概述
- 使用PHP制作文字水印
- 死磕《Effective Java中文版》-开篇
- react-native-wechat
- remove element
- 第二篇:变量类型转换和函数
- 1030: 判断直角三角形