【博览网】面向对象高级编程(上)——第三周课程笔记

第三周主要介绍C++中类与类之间的关系,主要包括复合、委托和继承这三个基本的关系。在这三个基本关系的基础上介绍了面向对象的程序开发方法,并且详细讲解了为面向对象程序开发方法提供基本支持的虚函数和多态特性。

一、三种基本关系
1.Composition 复合关系
这里写图片描述
如上述代码所示,queue与deque便是一个基本的复合关系,它表示queue类拥有deque类的对象,二者之间的关系是has-a关系。内存上,复合关系的类的对象的大小是其所包含对象的内存大小的直接累加。
2.Delegation委托关系
这里写图片描述
如上述代码所示,String和StringRep之间便是委托关系。委托关系与复合关系类似,表示的也是has-a。二者的区别在于,委托关系的内部是使用指针来指向所包含的元素的,而复合关系则直接包含该元素。
使用委托关系可以实现类的不同对象使用同一对象来实现其基本功能。
3.Inheritance继承关系
这里写图片描述
继承是C++的一个语言特性,其语法结构如上所示。被继承的类称为基类或者父类,继承的类称为子类或者派生类。子类会拥有父类的全部属性和方法,因此二者之间是is-a的关系。

二、虚函数和多态
从代码复用的角度来看,继承关系完全可以通过复合关系来实现,那么为什么C++需要实现继承这样的语法特性呢?除了语法上更加简介外,另一个重要的原因是C++具有虚函数,通过虚函数可以实现符合关系难以实现的许多功能。
C++的类成员函数分为以下几个类别:
• non-virtual函数:不希望子类重新定义
• virtual函数:希望子类重新定义,且父类有默认定义
• pure virtual函数:子类必须重新定义,父类没有默认定义
其定义代码如下所示:

class Shape{
public:
    virtual void draw() const = 0;    //pure virtual
    virtual void error(const std::string& msg);  //impure virtual
    int objectID() const;  //non-virtual
}

其语法特性如下:
• non-virtual函数:子类可以覆盖该函数,父类指针指向子类对象时,调用父类函数
• virtual函数:子类可以覆盖该函数,父类指针指向子类对象时,调用子类函数
• pure virtual函数:子类必须覆盖该函数,父类指针指向子类对象时,调用子类函数
注:从以上特性可知,父类的析构函数必须声明为虚函数,否则会导致子类析构函数未被调用产生内存泄漏的问题。

所谓多态是指程序在运行时,由于子类实现的不同,调用同一个函数,有不同的执行效果。比如作为父类Shape类,实现了一个getArea()虚函数,由于其指针所指的对象可能为Rectangle,也有可能为Circle类,因此其getArea()函数的执行方式必然不同。多态的特性在面向对象程序设计和设计模式中有着广泛的运用。

三、构造函数和析构函数
构造函数执行顺序:
父类构造函数->子类中对象构造函数->子类构造函数
析构函数执行顺序:
子类析构函数->子类中对象析构函数->父类析构函数

四、两个设计模式的例子(内容后面课程会进行更为详细的讲解)
1.Compositie模式
这里写图片描述
2.Prototype模式
这里写图片描述

五、补充:虚函数的底层实现
关于虚函数的实现,在这里再补充一下。在第二周中的课堂中有提到过对象的内存是如何分配的(上周笔记中没有,因为觉得比较复杂,没写上去)。我们知道,对象中只存储了自己所含有的数据内容,类的方法是存在另一个地方的,在调用方法是通过this指针将对象的数据传递到方法中去。因此,在逻辑上,类的数据和方法是放在一起的,但是在底层二者仍然是分开的。
由以上的分析可知,父类的指针并没有办法获取到其所指对象的类型信息,那么它又是如何实现多态的呢?答案是通过虚函数表实现。
这里写图片描述
如图所示,在有虚函数的对象中,往往会比别的对象多一个数据项——虚函数表指针,它指向了一个指针数组,这个指针数组中的指针指向了对象中所有存在的虚函数。在调用虚函数时,通过该表便可以找到实际对象所对应的虚函数了。
可见,虚函数本身比非虚函数在调用效率上有一定的差距,因此在确定不会被覆盖的函数上,最好不要使用虚函数。
详细内容见:
http://blog.csdn.net/haoel/article/details/1948051/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值