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 继承的一个特性相关推荐

  1. Python中的对象,类,super()函数

    对象:(1)外观的特征 (2)正在做的事情 比如:那个穿蓝色衣服的正在打球的帅哥  类:属性(静态的变量)+方法(函数)是对对象的近似 类名约定是以大写字母开始的 类的出现: 是为了使得对象可以进行大 ...

  2. c++设计一个不能被继承的类

    摘要:使用友元.私有构造函数.虚继承等方式可以使一个类不能被继承,可是为什么必须是虚继承?背后的原理又是什么? 用C++实现一个不能被继承的类(例1) 1 #include <iostream& ...

  3. 【100题】第五十九题 用C++编写不能被继承的类

    一,题目 用C++设计一个不能被继承的类. 二,分析 在Java中定义了关键字final,被final修饰的类不能被继承.但在C++中没有final这个关键字. 首先想到的是在C++ 中,子类的构造函 ...

  4. 多态指针访问虚函数不能被继承的类快速排序N皇后问题插入排序堆排序merge归并排序栈上生成对象两个栈实现一个队列...

    多态 /*1. 要想实现覆盖(重写)父类必须声明为virtual,子类可以不声明为virtual.-->FunB()2. 派生类重写基类的虚函数实现多态,要求函数名.参数列表.返回值完全相同.( ...

  5. 基类成员的public访问权限在派生类中变为_C++ 派生类的构造函数(学习笔记:第7章 06)...

    派生类的构造函数[1] 默认情况 基类的构造函数不被继承; 派生类需要定义自己的构造函数. C++11规定 可用using语句继承基类构造函数. 但是只能初始化从基类继承的成员. 派生类新增成员可以通 ...

  6. 由创建一个不能被继承的类引发的对象模型的思考

    昨天吃饭和宽妹讨论起以前看过的如何创建一个不能被继承的类,具体实现见 http://blog.csdn.net/kuaile123/article/details/21321471 同学提到了第一种方 ...

  7. 程序员面试题精选100题(32)-不能被继承的类[C/C++/C#]

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

  8. [剑指offer]面试题48:不能被继承的类

    面试题48:不能被继承的类 题目:用C++设计一个不能被继承的类. ❖ 常规的解法:把构造函数设为私有函数 很多人都能够想到,在 C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动 ...

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

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

最新文章

  1. 利用OpenCV、Python和Ubidots构建行人计数器程序(附完整代码)
  2. CVPR2020 best paper:对称可变形三维物体的无监督学习
  3. 通过页面埋点做监控却不影响性能?解密ARMS前端监控数据上报技术内幕
  4. leveldb原理和使用
  5. win2k cannot set the docm proportites
  6. 匹兹堡大学申请条件计算机科学,匹兹堡大学cs
  7. 修改freebsd的主机名
  8. Jeecg-Boot 2.1.4 版本发布,基于SpringBoot低代码平台
  9. 点云着色系列之按坐标轴着色效果展示
  10. 迈向人工通用智能与混合天玑芯片架构
  11. 【Vue US国际会议】使用Vue和NativeScript来开发吸引人的原生手机app
  12. Android记事本定时功能,Android如何实现记事本功能
  13. JAVA核心知识点--获取HttpServletRequest请求Body中的内容
  14. 基于139邮箱的新邮件到达免费短信提醒的研究与应用
  15. asp微信扫码签到源码
  16. 容器化一个简单的 Mern stack app
  17. shell脚本——学习笔记(包含应用案例)
  18. 关于DCDC选型OVP的经验
  19. 高通平台开发系列讲解(外设篇)高通Camera用户层移植
  20. 用Python调用Graphviz生成复杂股权关系图

热门文章

  1. P1020 导弹拦截(LIS)
  2. [driver]linux内核动态加载模块
  3. C#调用SQL Server分页存储过程
  4. Spring 依赖注入方式详解
  5. C++中多态性学习(上)
  6. wcf中的使用全双工通信(转)
  7. 修改Windows远程登录端口号
  8. left join on 后and 和 where 的区别
  9. ASP.NET MVC编程——控制器
  10. 第一次刷Leetcode,为什么耗费很多时间