用C++实现一个不能被继承的类
#include<iostream>
using namespace std;
class Gradpa
{
friend class Parent;//声明public或者private都无影响
private:
Gradpa(){
cout<<"I m Gradpa"<<endl;
};
~Gradpa(){}; }; class Parent: virtual public Gradpa
{
public:
Parent(){
cout<<"I m Parent"<<endl;
};
~Parent(){};
}; class Child:public Parent
{
public:
Child(){
cout<<"I m Child"<<endl;
}
~Child(){}
}; int main()
{
//Gradpa* gra=new Gradpa; //构造函数声明为private,不能直接访问
Parent* par=new Parent; //通过声明一个friend 类,访问private的构造函数
Child * chd=new Child; //子类能够继承父类,但是Parent加上virtual 后变成虚继承,Child类就得直接去访问Gradpa,导致出错。保证Parent类不能被继承
system("pause");
return ; }
错误 1 error C2248: “Gradpa::Gradpa”: 无法访问 private 成员(在“Gradpa”类中声明) e:\my projects\不能被继承的类.cpp 26
可参考详细转载,转载地址为:http://blog.163.com/xiangzaihui@126/blog/static/166955749201182295845689/
在C++中,子类的构造函数会自动调用父类的构造函数子类的析构函数也会自动调用父类的析构函数。
要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。
那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。
可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?这难不倒我们,我
们可以通过定义静态来创建和释放类的实例。基于这个思路,我们可以写出如下的代码:
class FinalClass1
{
public :
static FinalClass1* GetInstance()
{
return new FinalClass1;
}
static void DeleteInstance( FinalClass1* pInstance)
{
delete pInstance;
pInstance = 0;
}
private :
FinalClass1() {}
~FinalClass1() {}
};
这个类在基本上就能实现不能继承的功能。但是每次如果你都用这样一个类的话,估计你到最后不是你的程序崩溃了,而是你自己崩溃的更早。
因此,我们这样设计。
class CFinalClassMixin
{
friend class CParent;
private:
CFinalClassMixin(){}
~CFinalClassMixin(){}
};
class CParent: public CFinalClassMixin
{
public:
CParent(){}
~CParent(){}
};
class CChild : public CParent
{
};
但是发现没有用,想一想也是,CChild构造函数调用CParent的构造函数,而CParent的构造函数再调用CFinalClassMixin的构造函数,很显然是合法的。
我估计你也想骂了,唧唧歪歪讲了这么就还是不行。
但是请你想想,如果我是在CChild的构造函数直接调用CFinalClassMixin的构造函数,而CFinalClassMixin的构造函数是private,不能被调用,那我们岂不是达到了目的,但是我们如何才能在CChild中直接调用CFinalClassMixin的构造函数而不是通过CParent去调用了。
给你一分钟去想想。。。。。。。。。。。。。。
哈哈虚继承,虚继承刚好可以实现上述目的。
因此:
class CFinalClassMixin
{
friend class CParent;
private:
CFinalClassMixin(){}
~CFinalClassMixin(){}
};
class CParent: virtual public CFinalClassMixin
{
public:
CParent(){}
~CParent(){}
};
哈哈发现CParent不再可以被继承了。
如果你不懂虚继承是个神马东东的话,你可以参考我的另外一篇文章:
虚继承
如果你看懂了,我相信你就懂了上述的方法了。
用C++实现一个不能被继承的类的更多相关文章
- 用C++设计一个不能被继承的类(用私有构造函数+友元函数)
题目:用C++设计一个不能被继承的类. 分析:这是Adobe公司2007年校园招聘的最新笔试题.这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目. 在Java中定义了关键字f ...
- 探讨C++实现一个不可被继承的类
C#和Java都提供了一种机制让一个类不能被继承,如C#中的sealed关键字和Java的final关键字,然而C++程序员就没这么好命了.不过C++也可以模拟出这种效果,原理基于:子类的构造函数会自 ...
- 用C++设计一个不能被继承的类(转)
在Java 中定义了关键字final,被final修饰的类不能被继承. 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被 ...
- C++设计实现一个不能被继承的类
C++不同于Java,Java中被final关键字修饰的类不能被继承,C++能实现不被继承的类,但是需要自己实现. 为了使类不被继承,最好的办法是使子类不能构造父类的部分,此时子类就无法实例化整个子类 ...
- 面试题48:用C++设计一个不能被继承的类
解法一:把构造函数设为私有 将构造函数定义为私有,然后通过定义公有的静态函数来创建和释放类的实例. { public: static SealedClass1* GetInstance() { ret ...
- 用C++ 设计一个不能被继承的类
http://blog.sina.com.cn/s/blog_69d9bff30100odlz.html 在Java 中定义了关键字final ,被final 修饰的类不能被继承.但在C++ 中没有f ...
- 用c++编写一个不能被继承的类(但是可以在类外部定义该类的对象)
据我们知道,我们只要把类的构造函数和析构函数定义为private类型,那么就不能够在外部建立给类的对象,也就不能以给类为基类进行继承,因为如果继承,建立对象的时候将要调用基类的构造函数,但是因为为pr ...
- c++设计一个无法被继承的类
要求是该类不能被继承,但是能够像正常的类一样使用.那么一下方法就不符合题目要求: 1.构造函数和析构函数设置为private.这样就不能定义一个类的实例 2.类似于singleton模式那样,定义一个 ...
- C++设计一个不能被继承的类
1. 方法一 将构造函数和析构函数设置为私有函数,重新定义公有的静态函数来创建和释放类. #include "stdafx.h" #include <iostream> ...
随机推荐
- Swift基础之Delegate方法的使用
本文简单介绍了使用Delegate方法的进行值的传递,改变上一个界面的字体大小和颜色 首先创建一个导航视图: let viewC = ViewController(); let navi ...
- [RDLC]一步一步教你使用RDLC(一)
一:加数据集,并且命名为Quotation,如下图所示: 二: 添加一张报表,命名为Quotation,如下图所示: 向报表中添加"表"这一项,如下图所示: 这时就弹出一个选择数据 ...
- java的hashcode(结合hashset讲解)
equals()跟hashcode()都可以用来比较对象.hashcode通过不同对象有不同的散列码来比较两个对象. hashcode方法把对象放到一个对象容器进行查找,算法好坏直接影响容器的存取效率 ...
- html5学习之旅-html5的简易数据库开发(18)
实际上是模拟实现html5的数据库功能,用键值对的方式. !!!!!!废话不多说 ,代码 index.html的代码 <!DOCTYPE html> <html lang=" ...
- Android热插拔事件处理详解
一.Android热插拔事件处理流程图 Android热插拔事件处理流程如下图所示: 二.组成 1. NetlinkManager: 全称是NetlinkManager.cpp位于And ...
- Rust语言之HelloWorld Web版
Rust语言之HelloWorld Web版 下面这篇文章值得仔细研读: http://arthurtw.github.io/2014/12/21/rust-anti-sloppy-programmi ...
- 1、libgdx简介
Libgdx 是一个跨平台和可视化的的开发框架.它当前支持Windows,Linux,Mac OS X,Android,IOS和HTML5作为目标平台. Libgdx允许你一次编写代码不经修改部署到多 ...
- Android不同系统版本依然能调用到正确的API方法Demo——Service调用startForeground举例
private static final Class<?>[] mSetForegroundSignature = new Class[] { boolean.class}; privat ...
- 【Android 应用开发】BluetoothServerSocket详解
一. BluetoorhServerSocket简介 1. 继承关系 public final class BluetoothServerSocket extends Object implement ...
- canvas的常见用法
Canvas canvas是一种抽象概念,是2D图形系统中的重要部分,canvas一系列函数最终都是android 2D图形库Skia的一些列封装,对应在SKCanvas.cpp.canvas在系统中 ...