C++ 中不能被继承的类实现,及从中体现virtual 继承的一个特性
C++ view第一期中给出了如何实现一个不能被继承的类的方法。
如下:
#ifdef NDEBUG
#define FINAL_CLASS
#else
#define FINAL_CLASS : public virtual Private::NonDerivableHelper //这里的关键是virtual 只要是virtual就不能继承
#endif
namespace Private
{
class NonDerivableHelper
{
protected:
NonDerivableHelper(int) { cout << "a" << endl;} //ADDED CTOR ARGUMENT
};
}
class NonDerivable FINAL_CLASS
{
public:
NonDerivable() : NonDerivableHelper(0) {cout << "b" << endl;} //PASS A DUMMY VALUE
};
class A: public NonDerivable
{
public:
A() { cout << "c" << endl;}
};
int main(int argc, char *argv[])
{
NonDerivable n;
A a;
return 0;
}
这里A试图继承 NonDerivable 类,但是编译器会报错
underivable.cc|55| 错误: 对‘Private::NonDerivableHelper::NonDerivableHelper()’的调用没有匹配的函数
underivable.cc|40| 附注: 备选为: Private::NonDerivableHelper::NonDerivableHelper(int)
underivable.cc|38| 附注: Private::NonDerivableHelper::NonDerivableHelper(const Private::NonDerivableHelper&)
这也就是选择virtual 继承的原因,选择virtual继承,构造函数时会跳过NonDerivable() : NonDerivableHelper(0) 而直接去调用
NonDerivableHelper(int)
在虚继承出现的继承层次中,总是在构造非虚基类之前构造虚基类。参考http://tech.ddvip.com/2009-07/1246614951125275.html。
即使是非virtual继承也是基类先被构造,但是构造函数的选择是要由子类决定的,如果子类不提供信息则才调用基类的默认构造函数。
而在这里的virtual继承使得首先就越过NonDerivable,直接去构造NonDerivableHelper。
做个小实验就清楚了
#ifdef NDEBUG
#define FINAL_CLASS
#else
#define FINAL_CLASS : public virtual Private::NonDerivableHelper //这里的关键是virtual 只要是virtual就不能继承
#endif
namespace Private
{
class NonDerivableHelper
{
protected:
NonDerivableHelper(int) { cout << "a" << endl;} //ADDED CTOR ARGUMENT
NonDerivableHelper() { cout << "a!" << endl;}
};
}
class NonDerivable FINAL_CLASS
{
public:
NonDerivable() : NonDerivableHelper(0) {cout << "b" << endl;} //PASS A DUMMY VALUE
};
class A: public NonDerivable
{
public:
A() { cout << "c" << endl;}
};
int main(int argc, char *argv[])
{
//A a;
NonDerivable n;
A a;
return 0;
}
运行结果
a
b
a!
b
c
将virtual 去掉
即 #define FINAL_CLASS : public Private::NonDerivableHelper //这里的关键是virtual 只要是virtual就不能继承
运行结果
a
b
a
b
c
OK, virtual 继承和非virtual继承在构造函数调用上的不同已经很清楚了,a与a!的区别。
C++ 中不能被继承的类实现,及从中体现virtual 继承的一个特性相关推荐
- Python中的对象,类,super()函数
对象:(1)外观的特征 (2)正在做的事情 比如:那个穿蓝色衣服的正在打球的帅哥 类:属性(静态的变量)+方法(函数)是对对象的近似 类名约定是以大写字母开始的 类的出现: 是为了使得对象可以进行大 ...
- c++设计一个不能被继承的类
摘要:使用友元.私有构造函数.虚继承等方式可以使一个类不能被继承,可是为什么必须是虚继承?背后的原理又是什么? 用C++实现一个不能被继承的类(例1) 1 #include <iostream& ...
- 【100题】第五十九题 用C++编写不能被继承的类
一,题目 用C++设计一个不能被继承的类. 二,分析 在Java中定义了关键字final,被final修饰的类不能被继承.但在C++中没有final这个关键字. 首先想到的是在C++ 中,子类的构造函 ...
- 多态指针访问虚函数不能被继承的类快速排序N皇后问题插入排序堆排序merge归并排序栈上生成对象两个栈实现一个队列...
多态 /*1. 要想实现覆盖(重写)父类必须声明为virtual,子类可以不声明为virtual.-->FunB()2. 派生类重写基类的虚函数实现多态,要求函数名.参数列表.返回值完全相同.( ...
- 基类成员的public访问权限在派生类中变为_C++ 派生类的构造函数(学习笔记:第7章 06)...
派生类的构造函数[1] 默认情况 基类的构造函数不被继承; 派生类需要定义自己的构造函数. C++11规定 可用using语句继承基类构造函数. 但是只能初始化从基类继承的成员. 派生类新增成员可以通 ...
- 由创建一个不能被继承的类引发的对象模型的思考
昨天吃饭和宽妹讨论起以前看过的如何创建一个不能被继承的类,具体实现见 http://blog.csdn.net/kuaile123/article/details/21321471 同学提到了第一种方 ...
- 程序员面试题精选100题(32)-不能被继承的类[C/C++/C#]
题目:用C++设计一个不能被继承的类. 分析:这是Adobe公司2007年校园招聘的最新笔试题.这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目. 在Java中定义了关键字f ...
- [剑指offer]面试题48:不能被继承的类
面试题48:不能被继承的类 题目:用C++设计一个不能被继承的类. ❖ 常规的解法:把构造函数设为私有函数 很多人都能够想到,在 C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动 ...
- 用C++ 设计一个不能被继承的类
题目:用C++ 设计一个不能被继承的类. 分析:这是Adobe 公司2007 年校园招聘的最新笔试题.这道题除了考察应聘者的C++ 基本功底外,还能考察反应能力,是一道很好的题目. 在Java 中定义 ...
最新文章
- 利用OpenCV、Python和Ubidots构建行人计数器程序(附完整代码)
- CVPR2020 best paper:对称可变形三维物体的无监督学习
- 通过页面埋点做监控却不影响性能?解密ARMS前端监控数据上报技术内幕
- leveldb原理和使用
- win2k cannot set the docm proportites
- 匹兹堡大学申请条件计算机科学,匹兹堡大学cs
- 修改freebsd的主机名
- Jeecg-Boot 2.1.4 版本发布,基于SpringBoot低代码平台
- 点云着色系列之按坐标轴着色效果展示
- 迈向人工通用智能与混合天玑芯片架构
- 【Vue US国际会议】使用Vue和NativeScript来开发吸引人的原生手机app
- Android记事本定时功能,Android如何实现记事本功能
- JAVA核心知识点--获取HttpServletRequest请求Body中的内容
- 基于139邮箱的新邮件到达免费短信提醒的研究与应用
- asp微信扫码签到源码
- 容器化一个简单的 Mern stack app
- shell脚本——学习笔记(包含应用案例)
- 关于DCDC选型OVP的经验
- 高通平台开发系列讲解(外设篇)高通Camera用户层移植
- 用Python调用Graphviz生成复杂股权关系图