设为首页 加入收藏

TOP

【C++研发面试笔记】2. 多态性(二)
2016-10-08 11:31:13 】 浏览:471
Tags:研发 面试 笔记 多态性
模板的非类型形参也就是内置类型形参,如template class B{};其中int a就是非类型的模板形参。
2、 非类型形参在模板定义的内部是常量值,也就是说非类型形参在模板的内部是常量。
3、非类型模板的形参只能是整型、指针和引用,像 double,String, String **这样的类型是不允许的。但是double &,double *对象的引用或指针是正确的。

2.3.4 操作符重载

运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据导致不同类型的行为。
运算符重载的实质是函数重载。在实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要调用达标函数。
不能重载的运算符只有五个,它们是:成员运算符“.”、指针运算符“*”、作用域运算符“::”、“sizeof”、条件运算符“?:”。
运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。
运算符重载为类的成员函数的一般语法形式为:

函数类型 operator 运算符(形参表) { 函数体; } 

运算符重载为类的友元函数的一般语法形式为:

friend 函数类型 operator 运算符(形参表) { 函数体; }

2.3.5 拷贝构造函数

拷贝构造函数嘛,当然就是拷贝和构造了,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。代码结构如下:

Class X{ public:   X();   X(const X&);//拷贝构造函数 }

如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的浅拷贝自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。
深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,只是定义了新的指针,就是浅拷贝。

C语言中可以通过函数指针来实现部分泛型
C语言的泛型处理


2.4 动态绑定和静态绑定

1、静态对象:对象在声明时采用的类型。是在编译期确定的。
2、动态对象:指对象当前的类型,是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。关于对象的静态类型和动态类型,看一个示例:

class B { } class C : public B { } class D : public B { } D* pD = new D();//pD的静态类型是它声明的类型D*,动态类型也是D* B* pB = pD;//pB的静态类型是它声明的类型B*,动态类型是pB所指向的对象pD的类型D* C* pC = new C(); pB = pC;//pB的动态类型是可以更改的,现在它的动态类型是C* 

3、静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
4、动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

class B { void DoSomething(); virtual void vfun(); } class C : public B { void DoSomething();//首先说明一下,这个子类重新定义了父类的no-virtual函数,这是一个不好的设计,会导致名称遮掩;这里只是为了说明动态绑定和静态绑定才这样使用。 virtual void vfun(); } class D : public B { void DoSomething(); virtual void vfun(); } D* pD = new D(); B* pB = pD; 

在这里,虽然pD和pB都指向同一个对象,但pD->DoSomething()和pB->DoSomething()并不是调用同一个函数。因为函数DoSomething是一个no-virtual函数,它是静态绑定的,也就是编译器会在编译期根据对象的静态类型来选择函数。pD的静态类型是D*,那么编译器在处理pD->DoSomething()的时候会将它指向D::DoSomething()。同理,pB的静态类型是B*,那pB->DoSomething()调用的就是B::DoSomething()。
而pD->vfun()和pB->vfun()调用的是同一个函数。因为vfun是一个虚函数,它动态绑定的,也就是说它绑定的是对象的动态类型,pB和pD虽然静态类型不同,但是他们同时指向一个对象,他们的动态类型是相同的,都是D*,所以,他们的调用的是同一个函数:D::vfun()。
上面都是针对对象指针的情况,对于引用(reference)的情况同样适用。
指针和引用的动态类型和静态类型可能会不一致,但是对象的动态类型和静态类型是一致的。D D; D.DoSomething()和D.vfun()永远调用的都是D::DoSomething()和D::vfun()。
总结一句话,只有虚函数才使用的是动态绑定,其他的全部是静态绑定。
特别需要注意的地方
当缺省参数和虚函数一起出现的时候情况有点复杂,因为虚函数是动态绑定的,而为了执行效率,缺省参数是静态绑定的。 所以绝不重新定义继承而来的缺省参数。


2.5 多继承的对象结构

已知:
class ClassC : public ClassA,public ClassB
下面这张图说明多继承下的对象结构:
这里写图片描述

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【C++研发面试笔记】11. 基本数据.. 下一篇【C++研发面试笔记】10. 基本数据..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目