用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> ...
随机推荐
- 【一天一道LeetCode】#64. Minimum Path Sum.md
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- ZooKeeper实现命名服务
使用场景 命名服务就是提供名称的服务,Zookeeper的命名服务有两个应用方面.一个是提供类似JNDI功能,另一个是制作分布式的序列号生成器. JNDI功能,我们利用Zookeep ...
- DFS迷宫递归所有路径 新手入门
这篇文章写给自己以后复习和个个入门朋友:提示同学们一定耐心看完解释 哪怕看得很难受,我是新手我懂大家的心烦.看完后慢慢体会代码 我们假设迷宫为如下状况: {0,0,1,0} ...
- SpriteBuilder改变布局后App运行出错代码排查
原来整个关卡场景放在GameScene.ccb中,后来觉得移到专门的Level.ccb比较好. 移动过后编译运行,只要移动Player的胳膊发射子弹时,Xcode报错: g due to Chipmu ...
- python异常处理和断言
http://blog.csdn.net/pipisorry/article/details/21841883 关于异常处理有必要么的讨论 最重要的问题是你在开发过程中隐藏了bug,如果当时你没加这个 ...
- Java学习笔记(二)事件监听器
Java实现对组件事件(如单击.输入等)的监听和JavaScript类似,都是先添加Listener,再写触发函数,不同的是,Java实现监听前必须使用implements将各个接口添加到类内. 相关 ...
- Lucene 学习资料
个机制的结合.关于中文的语言分析算法,大家可以在Google查关键词"wordsegment search"能找到更多相关的资料. 安装和使用 下载:http://jakarta. ...
- OpenCV OpenGL手写字符识别
另外一篇文章地址:这个比较详细,但是程序略显简单,现在这个程序是比较复杂的 http://blog.csdn.net/wangyaninglm/article/details/17091901 整个项 ...
- How to Send an Email Using UTL_SMTP with Authenticated Mail Server
In this Document Goal Solution References APPLIES TO: PL/SQL - Version 9.2.0.1 to 12.1.0.1 [Re ...
- 基于Bresenham和DDA算法画线段
直线:y=kx+b 为了将他在显示屏上显示出来,我们需要为相应的点赋值,那么考虑到计算机的乘法执行效率,我们肯定不会选择用Y=kx+b这个表达式求值,然后进行画线段. 我们应当是将它转化为加法运算. ...