#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++实现一个不能被继承的类的更多相关文章

  1. 用C++设计一个不能被继承的类(用私有构造函数+友元函数)

    题目:用C++设计一个不能被继承的类. 分析:这是Adobe公司2007年校园招聘的最新笔试题.这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目. 在Java中定义了关键字f ...

  2. 探讨C++实现一个不可被继承的类

    C#和Java都提供了一种机制让一个类不能被继承,如C#中的sealed关键字和Java的final关键字,然而C++程序员就没这么好命了.不过C++也可以模拟出这种效果,原理基于:子类的构造函数会自 ...

  3. 用C++设计一个不能被继承的类(转)

    在Java 中定义了关键字final,被final修饰的类不能被继承. 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被 ...

  4. C++设计实现一个不能被继承的类

    C++不同于Java,Java中被final关键字修饰的类不能被继承,C++能实现不被继承的类,但是需要自己实现. 为了使类不被继承,最好的办法是使子类不能构造父类的部分,此时子类就无法实例化整个子类 ...

  5. 面试题48:用C++设计一个不能被继承的类

    解法一:把构造函数设为私有 将构造函数定义为私有,然后通过定义公有的静态函数来创建和释放类的实例. { public: static SealedClass1* GetInstance() { ret ...

  6. 用C++ 设计一个不能被继承的类

    http://blog.sina.com.cn/s/blog_69d9bff30100odlz.html 在Java 中定义了关键字final ,被final 修饰的类不能被继承.但在C++ 中没有f ...

  7. 用c++编写一个不能被继承的类(但是可以在类外部定义该类的对象)

    据我们知道,我们只要把类的构造函数和析构函数定义为private类型,那么就不能够在外部建立给类的对象,也就不能以给类为基类进行继承,因为如果继承,建立对象的时候将要调用基类的构造函数,但是因为为pr ...

  8. c++设计一个无法被继承的类

    要求是该类不能被继承,但是能够像正常的类一样使用.那么一下方法就不符合题目要求: 1.构造函数和析构函数设置为private.这样就不能定义一个类的实例 2.类似于singleton模式那样,定义一个 ...

  9. C++设计一个不能被继承的类

    1. 方法一 将构造函数和析构函数设置为私有函数,重新定义公有的静态函数来创建和释放类. #include "stdafx.h" #include <iostream> ...

随机推荐

  1. Zookeeper实现数据的发布和订阅

    使用场景        当一个对象的改变,需要通知其他对象而且不知道要通知多少个对象,可以使用发布订阅模式 .在分布式中的应用有配置管理(Configuration Management) .集群管理 ...

  2. leetcode之 Generate Parentheses

    题目:http://oj.leetcode.com/problems/generate-parentheses/ 描述:给定一个非负整数n,生成n对括号的所有合法排列. 解答: 该问题解的个数就是卡特 ...

  3. Ajax 初步学习总结

    Ajax是什么 Ajax是(Asynchronous JavaScript And XML)是异步的JavaScript和xml.也就是异步请求更新技术.Ajax是一种对现有技术的一种新的应用,不是一 ...

  4. quartz实现定时功能实例详解(servlet定时器配置方法)

    Quartz是一个完全由java编写的开源作业调度框架,下面提供一个小例子供大家参考,还有在servlet配置的方法 Quartz是一个完全由java编写的开源作业调度框架,具体的介绍可到http:/ ...

  5. Android 5.0 SEAndroid下如何获得对一个内核节点的访问权限

    -9]* u:object_r:tty_device:s0 # We add here /dev/wf_bt              u:object_r:wf_bt_device:s0 wf_bt ...

  6. 《java入门第一季》之参数引用

    Java中的参数传递问题: 基本类型:形式参数的改变对实际参数没有影响. 引用类型:形式参数的改变直接影响实际参数. */ class ArgsDemo { public static void ma ...

  7. Linux进程管理(第二版) --进程管理命令

    进程管理命令 一.查看用户信息.5.15 分钟内的系统的,优先值越小,优先权越大 ] 1.nice 指定程序运行的优先级 格式 nice -n command 例如 nice -5 myprogrem ...

  8. objective-c如何在linux下进入Modern模式

    自从apple的obj-c进入2.0后,出现了相对于Legacy模式的Modern模式:Modern模式中出现了一些高级功能(比如ARC),并且出现了一些新的字面语法,新旧模式的差别可以参考apple ...

  9. Redis 协议为例谈简单的协议分析

    怎样去研究一个协议的过程,协议的格式,好处,怎么样模拟发包等,下面是一个简单的过程记录. 研究的步骤: 协议相关的资料,RFC,官方文档等.弄清楚协议工作在4层还是7层,是二进制还是文本协议等 抓包, ...

  10. 《老罗的Android之旅》导读PPT

    虽然好几个月没更新博客了,但是老罗一直有在准备可以分享的东西的.除了早前在微博分享Android4.2相关技术之外,这次还特意准备了13个PPT,总结之前所研究过的东西.内容从Android组件设计思 ...