C++中final类的实现
来源:互联网 发布:淘宝打包员好做吗 编辑:程序博客网 时间:2024/06/06 11:37
namespace Private{ class NonDerivableHelper { NonDerivableHelper() {} friend class NonDerivable; }; } #ifdef NDEBUG #define FINAL_CLASS #else #define FINAL_CLASS : private virtual Private::NonDerivableHelper #endif class NonDerivable FINAL_CLASS { ... };
在《C++ View》第一期P25,《C++中常用的几个小技巧》中,提供了实现final类的方法。
这里我们先不将方法写全,而是抽取其中精华的部分来看。
在看代码之前,首先我们要了解的知识包括,构造函数,私有访问,友元,私有继承,虚拟继承,以及虚拟继承下的特殊初始化语义(虚拟基类的初始化变成了最终派生类的责任)。
这些可以参考《C++ Primer》第三版中的相关内容,因为内容较多,需要整理一下,再行发出。
1.构造函数
在《C++ View》第一期P25,《C++中常用的几个小技巧》中,提供了实现final类的方法。
这里我们先不将方法写全,而是抽取其中精华的部分来看。
在看代码之前,首先我们要了解的知识包括,构造函数,私有访问,友元,私有继承,虚拟继承,以及虚拟继承下的特殊初始化语义(虚拟基类的初始化变成了最终派生类的责任)。
这些可以参考《C++ Primer》第三版中的相关内容,因为内容较多,需要整理一下,再行发出。
1.构造函数 ----- 待整理
2.私有访问 ----- 待整理
3.友元 ----- 待整理
4.私有继承
private继承是因为父类提供了更多的接口,而子类并不需要这些接口来对外,子类只是在提供自己接口的时候,希望重用父类的实现。从而private继承父类,这样父类的公有方法在子类中全部成为了private方法,只有子类的成员函数和友元类可以访问这些方法,而其他使用均为非法。
5.虚拟继承 ----- 待整理
6.虚拟继承下的特殊初始化语义 ----- 待整理
所有代码均为完整代码,非代码片段,可以直接使用;所有代码均经过测试,测试平台VS2005。
一些代码不能编译通过,正是说明了语言特性,请联系上下文使用代码。
代码1:
#include <iostream>using namespace std;class NonDerivableHelper{private:NonDerivableHelper() {cout<<"base1"<<endl;}friend class NonDerivable;};class NonDerivable:private NonDerivableHelper{public:NonDerivable():NonDerivableHelper(){cout<<"base2"<<endl;}};class Derive:public NonDerivable{public:Derive():NonDerivable(){cout<<"Derive"<<endl;}};int main(){Derive d;return 1;}
代码1中Derive类可以继承NonDrivable类,NonDerivable类可以使用NonDerivableHelper的私有
构造函数方法(因为NonDerivableHelper类声明NonDerivable类为其友元)。从而可以继承成功。
代码2:
#include <iostream>using namespace std;class NonDerivableHelper{private:NonDerivableHelper() {cout<<"base1"<<endl;}friend class NonDerivable;};class NonDerivable:private virtual NonDerivableHelper{public:NonDerivable():NonDerivableHelper(){cout<<"base2"<<endl;}};class Derive:public NonDerivable{public:Derive():NonDerivable(){cout<<"Derive"<<endl;}};int main(){Derive d;return 1;}
在11行的类继承时,加上virtual继承,这样Derive类就无法再对NonDerivable类进行继承了,NonDerivable
即我们所要实现的final类。会在编译时出现错误。这时的疑问就是,无论如何都会出现无法继承吗?
OK,第一种情况:Derive类自己不实现构造函数,使用默认的构造函数。
代码3:
#include <iostream>using namespace std;class NonDerivableHelper{private:NonDerivableHelper() {cout<<"base1"<<endl;}friend class NonDerivable;};class NonDerivable:private virtual NonDerivableHelper{public:NonDerivable():NonDerivableHelper(){cout<<"base2"<<endl;}};class Derive:public NonDerivable{public:};int main(){Derive d;return 1;}
这时我们编译发现,还是编译错误:cannot access private member declared in class 'NonDerivableHelper'说明默认还是去调用了基类的构造函数。第二种情况:NonDerivable类也不去实现构造函数而使用默认构造函数。代码4:
#include <iostream>using namespace std;class NonDerivableHelper{private:NonDerivableHelper() {cout<<"base1"<<endl;}friend class NonDerivable;};class NonDerivable:private virtual NonDerivableHelper{public:};class Derive:public NonDerivable{public:};int main(){Derive d;return 1;}
这时也会发现,同样的编译错误。
说明Derive类不是通过NonDerivable类来调用的基类的构造函数。第三种情况,将NonDerivableHelper中的friend class NonDerivable的友元声明去掉。代码5:
#include <iostream>using namespace std;class NonDerivableHelper{private:NonDerivableHelper() {cout<<"base1"<<endl;}};class NonDerivable:private virtual NonDerivableHelper{public:};class Derive:public NonDerivable{public:};int main(){Derive d;return 1;}
这时还是和上面报的一样的错误。Derive不能访问基类的private方法。第四种情况:将NonDerivableHelper中的friend class NonDerivable的友元声明去掉。将NonDerivable的继承修改为private继承。代码6:
这时我们发现,编译错误改变了,现在是NonDerivable类不能访问NonDerivableHelper类的private构造函数了。这也是正确的,因为只有该类的友元与该类的成员函数可以访问private成员,而子类是不可以的。这个例子与下面的相同:
1 #include <iostream> 2 using namespace std; 3 4 class NonDerivableHelper 5 { 6 private: 7 NonDerivableHelper() {cout<<"Base1"<<endl;} 8 friend class NonDerivable; 9 };10 11 class NonDerivable:private NonDerivableHelper12 {13 private:14 NonDerivable() {}15 };16 17 class Derive:public NonDerivable18 {19 20 };21 22 int main()23 {24 Derive d;25 }
此时,编译错误。Derive不能够访问父类NonDerivable的对象。从上面的代码可以了解virtual继承,private访问控制,友元的一些关系。
- C++中final类的实现
- C++中如何实现final类
- 类中static final域和final域的区别
- private static final long serialVersionUID在实现序列化的类中出现的意义
- private static final long serialVersionUID在实现序列化的类中出现的意义
- private static final long serialVersionUID在实现序列化的类中出现的意义
- private static final long serialVersionUID在实现序列化的类中出现的意义
- 如何在C++中实现java final标识的类的功能
- C++如何实现类似JAVA中加了FINAL关键字的类
- java中final类的一些思考
- Java中常见的final类
- c++ final类实现
- JAVA中final的用法
- java中final的用法
- java中final的意义
- Java中final的用法
- java中final的意义
- java中final的意义
- android service 介绍
- 基于axis2的WebService获取客户端请求IP地址
- 深入理解 Android Activity的生命周期
- 动态显示文章发表时间的方法
- 利用apache的HttpClient组件得到http内容
- C++中final类的实现
- iis常见错误
- 关于0xa0
- ASP.NET页面之间传递值方式优缺点比较
- ASP.NET 如何取得 Request URL 的各个部分
- spring 拦截器例子
- 时间交换
- Steps to Re-Create ASM Diskgroups
- Steps To Migrate-Move a Database From Non-ASM to ASM And Vice-Versa