Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15011
  • 博文数量: 13
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 12
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-07 09:00
文章分类

全部博文(13)

文章存档

2015年(1)

2014年(12)

我的朋友
最近访客

分类: C/C++

2014-11-09 23:38:06

原文地址:实现不可继承的C++类 作者:yaoyabad

目的:构建一个不允许继承的类;试图冒犯者,直接让你在编译时就挂掉
注释:
A类是父类,作用是辅助B类不可被继承
B类是不可继承的类,即我们希望实现的类
D类是试图继承B类的类,结果是我们期望的:不能编译通过
为了测试,实现了一个main函数

a.h
  1. //父类
  2. #pragma once
  3. #include "P.h"

  4. template <class T> class A
  5. {
  6.     friend T;    //T为子类类型,便于子类可访问该类的私有构造和析构函数
  7. private:            //记得这里需要把构造和析构函数放在私有成员里面
  8.     A(void);
  9.     ~A(void);
  10. };

  11. //模板类的成员实现要和定义放在一个文件里面,否则编译出错

  12. template<class T>
  13. A<T>::A(void)
  14. {
  15.     cout<<"A::A(void)"<<endl;
  16. }

  17. template<class T>
  18. A<T>::~A(void)
  19. {
  20.     cout<<"A::~A(void)"<<endl;
  21. }
b.h
  1. //不可继承的类
  2. #pragma once
  3. #include "a.h"

  4. class B :
  5.     virtual public A<B>    //这里必须添加virtual,否则B类的子类还能继承B
  6. {
  7. public:
  8.     B(void);
  9.     ~B(void);
  10. };
b.cpp
  1. #include "B.h"
  2. #include "P.h"

  3. B::B(void)
  4. {
  5.     cout<<"B::B(void)"<<endl;
  6. }


  7. B::~B(void)
  8. {
  9.     cout<<"B::~B(void)"<<endl;
  10. }
d.h
  1. //试图继承不可继承B类的类,当然,这个类不会编译成功
  2. #pragma once
  3. #include "b.h"

  4. class D
  5.     :public B    //这里试图继承B类,可是会编译出错,目的达到了,哇咔咔
  6. {
  7. public:
  8.     D(void);
  9.     ~D(void);
  10. };
d.cpp
  1. #include "D.h"
  2. #include "P.h"

  3. D::D(void)
  4. {
  5.     cout<<"D::D(void)"<<endl;
  6. }


  7. D::~D(void)
  8. {
  9.     cout<<"D::~D(void)"<<endl;
  10. }
p.h
  1. //公共使用头文件
  2. #pragma once
  3. #include <iostream>
  4. using namespace std;
main.cpp
  1. //测试
  2. #include "B.h"
  3. #include "D.h"

  4. void test(void);

  5. int main(void)
  6. {
  7.     test();    
  8.     return 0;
  9. }

  10. void test(void)
  11. {
  12.     B b;    //这样是OK的
  13.     //D d;    //这样就是不OK的,其实不是这里通不过,是D类根本就不可以继承B类,哇咔咔
  14. }
最后给出D类在Visual Studio 2010上编译时的错误
  1. d.cpp(5): error C2248: 'A::A' : cannot access private member declared in class 'A'
  2. 1> with
  3. 1> [
  4. 1> T=B
  5. 1> ]
  6. 1> e:\program\c++\finalyclass\finalyclass\a.h(8) : see declaration of 'A::A'
  7. 1> with
  8. 1> [
  9. 1> T=B
  10. 1> ]
原理分析:
D类的构造函数不能构造爷爷类(A类),因为A类的构造函数是私有的,它当然无权访问了,失败是理所当然的
B类之所以可以构造父类(A类),是因为在A类中声明了其子类(B类)是A类的友元类(friend T);所以B类可以访问的A类的私有成员(包括构造和析构函数)
阅读(321) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~