Effective C++:绝不重新定义继承而来的缺省参数值

GD32单片机引脚复用指南:如何让JTAG接口的PA15/PB3发挥第二功能? 本文详细介绍了GD32F103Cx系列单片机如何通过AFIO模块进行引脚复用,特别是将默认用于JTAG调试接口的PA15、PB3等引脚释放为普通IO或复用功能引脚。文章从原理出发,结合代码实践,讲解了如何配置调试端口重映射,将JTAG引脚安全地转换为GPIO或定时器通道,并提供了常见问题排查与最佳实践,帮助开发者高效利用有限的引脚资源。 阅读详情

考虑下面这段程序:

#include <iostream>
using namespace std;

class Shape {
public:
    enum ShapeColor { Red, Green, Blue };
    virtual void draw(ShapeColor color = Red) const = 0;
};

class Rectangle : public Shape {
public:
    virtual void draw(ShapeColor color = Green) const {
        cout << "Rectangle::draw, color = " << color << endl;
    }
};

class Circle : public Shape {
public:
    virtual void draw(ShapeColor color) const {
        cout << "Circle::draw, color = " << color << endl;
    }
};

int main()
{
    /*
    Circle circle;
    circle.draw();      //编译出错
    */

    /*
    Shape *pc = new Circle;
    pc->draw();         //color = 0(Red)
    */

    /*
    Rectangle rtg;
    rtg.draw();         //color = 1(Green)
    */

    /*
    Shape *pr = new Rectangle;
    pr->draw();         //color = 0(Red)
    */

    return 0;
}
在分析这段程序之前,我们先明确几个概念。

静态类型:指它在程序中被声明时所采用的类型。

动态类型:指目前所指对象的类型。

例如上面的程序中,pr的动态类型是Rectangle,静态类型是Shape。

静态绑定:又名前期绑定(early binding),绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。

动态绑定:又名后期绑定(late binding),绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

virtual函数是动态绑定,意思是调用一个virtual函数时,究竟调用哪一份函数的实现代码,取决于发出调用的那个动态类型。

而缺省参数值是静态绑定。

因此对于第一段代码:

Circle circle;
circle.draw();      //编译出错
当我们以对象调用此函数,必须要指定参数值,circle的静态类型是Circle,在静态绑定下,函数并不从Shape继承其缺省参数值。

对于第二段代码:

Shape *pc = new Circle;
pc->draw();         //color = 0(Red)
此时可以不用指定参数,因为pc的动态类型是Circle,静态类型是Shape,通过动态绑定,它调用的是Circle的draw函数,但是通过静态绑定它继承了Shape的缺省参数Red。

对于第三段和第四段代码的表现结果,其原因则与上面类似。

如果我们想避免上面的麻烦,我们可以使用NVI(non-virtual interface)手法去替代:令base class内的一个public non-virtual函数调用private virtual函数,后者可被derived classes重新定义。这里我们可以让non-virtual函数指定缺省参数,而private virtual函数负责真正的工作。

class Shape {
public:
    enum ShapeColor { Red, Green, Blue };
    void draw(ShapeColor color = Red) const {           //如今它是non-virtual
        doDraw(color);                                  //调用一个virtual
    }
private:
    virtual void doDraw(ShapeColor color) const = 0;    //真正的工作在此处完成
};

class Rectangle : public Shape {
public:
    
private:
    virtual void doDraw(ShapeColor color) const;        //注意,不须指定缺省参数值
};
由于non-virtual函数应该绝对不被derived classes覆写,这个设计很清楚地使得draw函数的color缺省参数值总是为Red。





C++:47---绝不重新定义继承而来的缺省参数值 一、静态类型、动态类型静态类型:在被声明时所采用的的类型动态类型:目前所知对象的类型演示案例下面是一个继承体系class Shape {public:enum ShapeColor { ... 阅读详情

相关推荐

使用mindie:2.0.RC2-800I-A2-py311-openeuler24.03-lts制作一个通用的模型推理性能测试的镜像

本文详细介绍了在NPU环境下进行模型推理性能测试的完整流程。首先配置了测试所需的环境和设备信息,包括Python 3.10.9和3.11.6版本、测试脚本和镜像文件。然后分步骤说明了镜像制作过程:创建特权容器、安装Python 3.10.9、配置VLLM环境,并详细描述了测试容器的启动方法。最后提供了镜像打包和使用指南,包括如何加载镜像、启动容器、运行测试脚本(以DeepSeek-32B模型为例)以及更换测试模型的步骤。整个过程涉及环境变量配置、权限设置和服务启动等关键操作。

m0_50105717的博客 977

绝不重新定义继承而来的缺省参数值

子类对象调用父类的函数,但是父类函数中再次要求调用父类和子类都实现了得虚函数,那么这个时候调用的是?答案是: 记住:virtual 函数是动态绑定,而缺省参数值却是静态绑定。 意思是你可能会 在“调用一个定义于派生类内的virtual函数”的同时,却使用基类为它所指定的缺省参数值。  结论:绝不重新定义继承而来的缺省参数值!(可参考《Effective C++》条款37) 对于本例:

I feel lost 558

决不要重新定义继承而来的缺省参数值

决不要重新定义继承而来的缺省参数值,由权威的Effective C++讲述!

Effective C++:条款37:绝不重新定义继承而来的缺省参数值

由于重新定义继承而来的non-virtual函数是不正确的(见上一个条款),所以这个条款就将问题局限于:绝不重新定义继承一个带有缺省参数值的virtual函数。 (一) virtual函数是动态绑定的,而缺省参数却是静态绑定。  对象的所谓静态类型,是它在程序中被声明时所采用的类型。 你可能会在“调用一个定义于derived class 内的virtual函数”的同时,却使用了ba

u010470972的专栏 929

绝不重新定义继承而来的缺省参数值

序言 这里我们必须明白public 继承就是is a 关系,默认子类就是父类,虽然子类有自己新添加的功能,但是基于里氏代换原则,能用到父类的地方也能间接的应用到子类。也就意味着如果保持代码干净性,父类的non-virtual 函数(子类的公有特性提取),如果该函数有变动,可以考虑设为虚函数或者继承原有的non-virtual,子类再重新添加新函数对原有继承进行修改,这样是为了确保不要重新定义继承而...

liunanya的博客 394

Effective C++条款37:绝不重新定义继承而来的缺省参数值(Never redefine a function‘s inherited default parameter value)

Effective C++条款37:绝不重新定义继承而来的缺省参数值(Never redefine a function‘s inherited default parameter value)

CltCj的博客 562

实用经验 86 绝对不要重新定义继承而来的缺省参数

绝对不要重新定义继承而来的缺省参数,采用NVI方案:令基类的一个public non-virtual函数调用一个private virtual函数,后者可被派生类重新定义。可让non-virtual函数指定缺省参数,而private virtual函数负责真正实现工作。采用NVI这种方式,用户可采用静态的方式从基类类型的接口取得参数默认值,而派生类也可自由的变更函数的行为,而不用担心什么缺省初始化物了。

一鸣惊人的博客 239

Effective C++ 条款37:绝不重新定义继承而来的缺省参数值

Effective_C++_37

君鼎的博客 528

effective C++笔记之条款38: 绝不重新定义继承而来的缺省参数值

先看如下类层次结构 enum ShapeColor {RED, GREEN, BLUE}; class Shape { public: virtual void draw(ShapeColor color = RED) const = 0; … }; class Rectangle : public Shape { public: v

philips的专栏 2770

effective c++】条款三十七:绝不重新定义继承而来的缺省参数值

也许,这里正是你通往未来的某一把钥匙!

maybe_Tian_Xia的博客 326

绝不重新定义继承而来的缺省参数值——条款37

让我们一开始就将讨论简单化。你只能继承两种函数:virtual和non-virtual函数。然而重新定义继承而来的non-virtual函数永远是错误的(见条款36),所以我们可以安全地将本条款的讨论局限于“继承一个带有缺省参数值的virtual函数”。 这种情况下,本条款成立的理由就非常直接而明确了:virtual函数系动态绑定(dynamically bound),而缺省参数值却是静态绑定(statically bound)。 对象的所谓静态类型(st...

yj_android_develop的博客 395

C++ 绝不重新定义继承而来的缺省参数值

20180326 C++ 绝不重新定义继承而来的缺省参数值诚然在C++中,只能继承两种函数:虚(virtual)函数和非虚(non-virtual)函数。而重新定义一个继承而来的非虚(non-virtual)函数永远是错误的。所以本节主要讨论的就是“继承一个带有缺省参数值的虚(virtual)函数”。我们知道:/*******************************************...

weixin_39089680的博客 387

条款37:绝不重新定义继承而来的缺省参数值

条款37:绝不重新定义继承而来的缺省参数值内容:     审视了一下条款以后,我们可以换一种说法:绝不重新定义继承而来的virtual函数或non-virtual函数的缺省参数值.而在上一款中我们提到,绝对不要试图去重新定义继承而来的non-virtual函数,将这句话与本条款合并的话,我们就可以将本条款的内容简化为:绝不重新定义继承而来的virtual函数的缺省参数值.为什么继承而来的vir

scofieldzhu的专栏 2369

条款 37 :绝不重新定义继承而来的缺省参数值

条款 37 :绝不重新定义继承而来的缺省参数值 Never redefine a function’s inherited default parameter value 我们在条款36刚刚说过继承non-virtual函数是错误的。所以本条款更确切的说是:绝不重新定义继承而来的带有缺省参数值的virtual函数。理由很明确:virtual是动态绑定,而缺省参数是静态绑定 动态绑定又叫后期绑定,静态绑定又叫前期绑定。我们来复习一下两者区别吧: 我们先说一下静态类型和动态类型的概念:对象的所谓静态类型就是

weixin_45730130的博客 496

effective C++中条款37:绝不重新定义继承而来的缺省参数值

virtual 函数会动态绑定,而virtual函数的缺省参数值是静态绑定的。用一个base类型的指针p去指向一个derived类对象,通过p调用虚函数时,会动态绑定到实际所指对象中的函数;用一个derived类型的指针p2指向一个derived对象,由p2调用函数时,直接就是调用的derived中的函数,其参数值也是derived类中函数对应的参数值。 #include using name

yinqiaohua的专栏 838

Effective C++条款 37:绝不重新定义继承而来的缺省参数值

重新定义一个继承而来的non-virtual函数永远都是错误的,本条款的讨论限制在“带有缺省参数的virtual函数”。 virtual函数是动态绑定的,而缺省参数却是静态绑定。对象的所谓静态类型,是它在程序中被声明时所采用的类型。 #include "StdAfx.h" #include <iostream> using namespace std; ...

weixin_34055910的博客 186

绝不重新定义继承而来的缺省参数值

////////////////////////////////////////////////////////////////////////// // Effective C++. // Item 37: Never redefine a function's inherited default parameter value. // 绝不重新定义继承而来的缺省参数值 class IShap

Se7en的专栏 400

(一)通过JAVA连接SAP (sapjco3.jar在Windows和MacOS上的配置)-附件资源

(一)通过JAVA连接SAP (sapjco3.jar在Windows和MacOS上的配置)-附件资源

上一篇: C++私有继承
optcaelum
博客等级 码龄11年 0粉丝 10原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值