06--谈谈:C++类的“包含”机制
谈谈:C++类的“包含”机制
本人在学习Qt的时候发现了一个非常有趣的现象。有很多函数的调用方法都写成了如下的形式:
object.func().func2(); |
这令小弟着实不懂。在上面这段代码中,第一个对象调用它的成员函数func()是完全没有问题的,但是后面那个func2()就奇怪了。我们只知道,点运算符(.)的作用就是调用对象的成员,但是如果按照上面这个程序的字面意思来理解,就是对象object调用它的成员函数func(),然后函数func()再调用它的成员函数func2()。这怎么能解释得通哩??我们只知道对象有成员函数,但是从来没有听说过函数也可以有成员函数的啊。没有办法,只有翻C++的工具书,最后,居然发现了这个原来就是C++中的“包含”思想。那么究竟何为包含呢,且听小弟慢慢叙来......^_^
何为“包含”,其实说白了就是一个类可以包含另一个类的对象。即如下程序所示:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
class A{ //...};class B{ //... A a; A b;}; |
在上面这个程序中,我们定义了类A和类B。其中类B里面我们定义了类A的两个对象a和b。这样的情况就叫类B包含了类A。下面,我们用一个程序来看一下“包含”:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#include <iostream>using namespace std;class A{public: A(int i){x=i;cout<<"调用A类的构造函数\n";} ~A(){cout<<"调用A类的析构函数\n";}; void get() {cout<<"A类中X的值为:"<<x<<endl;}private: int x;};class B{public: B(int i,int j,int k):a(i),b(j),y(k){cout<<"调用B类的构造函数\n";} A geta(){return a;} A getb(){return b;} ~B(){cout<<"调用B类的析构函数\n";} void gety(){cout<<"B类中y的值为:"<<y<<endl;}private: A a; A b; int y;};int main(){ B b(1,2,3); b.geta().get(); b.getb().get(); b.gety(); return 0;} |
- 首先是对两个类进行分析:在上面这个程序中,我们定义了两个类A和B。其中可以看到,在类B的私有成员变量里面,我们定义了一个类B自己的成员变量,另外还定义了两个类A的对象a和b(22行和23行);另外在类B的公有函数中,我们定义了两个返回值为类A的函数:geta()和getb(),它们的作用就是返回在类B中定义的两个类A的对象a和b。在这里我们特别应该注意的是类B的构造函数:
B(inti,intj,intk):a(i),b(j),y(k){cout<<"调用B类的构造函数\n";}这个构造函数很有意思。我们可以看到它不仅初始化了自己的私有成员变量y,而且也顺带初始化了类A的两个对象a和b。那么它肯定会调用类A的构造函数,而且会调用两次。然后再调用一次B类自己的构造函数。那么析构的时候顺序应该就是相反的,首先调用B类的析构函数,然后再调用两次A类的析构函数。我们可以看到后面的程序输出图这样说滴,^_^。(见输出的红色框和黄色框)
现在我们再来看一看主函数中的东东。首先在程序的第29行,我们定义了B类的对象b,并调用了A类和B类的构造函数初始化了类A的对象a、b和类B的对象b。然后在程序的第30行我们就可以看到在博文一开始介绍的Qt中的东东。这里我们就搞不懂了,它们到底是干啥用的,什么都不说了,先看一下运行结果:

我们可以看到,返回的类A的对象a中x的值为1,另外一个类A的对象b中x的值为2。好了,豁然开朗了,我们来解释一下程序第30行和31行。第29行用类B的对象b来调用成员函数geta(),该函数是在17行定义的,作用就是返回类A的对象a,因此第30行
b.geta().get();就相当于
A a(1);a.get();这里的原因就是,因为b.geta()返回的是x的成员值为1的对象a,所以再调用类A的get()函数就可以省略了对象a了。那么同理,程序第31行就相当于
A b(2);b.get();这就说明了类B可以通过成员函数来访问被包含的类A对象的成员变量。就是文章一开始提到的方式,其实它是隐藏了声明类A的对象,因为由于包含的原因,类B已经帮类A搞定了对象的声明了~~~
OK咯,解决了Qt这个问题,我也顺带地搞懂了包含这个概念,嘿嘿......好了,收工!!!
06--谈谈:C++类的“包含”机制的更多相关文章
- Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...
- 深入理解Java虚拟机(类文件结构+类加载机制+字节码执行引擎)
目录 1.类文件结构 1.1 Class类文件结构 1.2 魔数与Class文件的版本 1.3 常量池 1.4 访问标志 1.5 类索引.父索引与接口索引集合 1.6 字段表集合 1.7 方法集合 1 ...
- Action类的工作机制
Action类的工作机制 Execute()方法包含以下参数 ActionMapping:包含了这个Action的配置信息,和struts-config.xml文件中的<action>元素 ...
- JVM专题1: 类和类加载机制
合集目录 JVM专题1: 类和类加载机制 Java对象的结构 在HotSpot虚拟机中, 对象在内存中存储的布局可以分为3块区域 对象头Header 实例数据Instance Data 对齐填充Pad ...
- Java虚拟机JVM学习07 类的卸载机制
Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...
- Cache【硬盘缓存工具类(包含内存缓存LruCache和磁盘缓存DiskLruCache)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 内存缓存LruCache和磁盘缓存DiskLruCache的封装类,主要用于图片缓存. 效果图 代码分析 内存缓存LruCache和 ...
- 多态时最好将基类的析构函数设为virtual、 C++中两个类相互包含引用问题 (转载)
多态:http://blog.csdn.net/tmljs1988/article/details/8146521 C++中两个类相互包含引用问题:http://blog.csdn.net/leo11 ...
- java定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积
需求如下:(1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积. (2)定义一个类PassObject,在类中定义一个方法pri ...
- 黑马基础阶段测试题:创建Phone(手机)类,Phone类中包含以下内容:
package com.swift; public class Phone { private String pinpai; private int dianliang; public String ...
随机推荐
- Django——1 环境搭建
Django 什么是Django 使用前的准备工作 新建项目 开启服务器 新建APP 简单实战 什么是Django框架 http服务器:用来接受用户请求,并将请求转发给web应用框架进行处理.Web应 ...
- 【[Offer收割]编程练习赛13 C】 一人麻将
[题目链接]:http://hihocoder.com/problemset/problem/1503 [题意] [题解] 一直在纠结如果没胡的话要扔掉哪一个麻将; 但其实可不用扔的,全部存起来就好了 ...
- mysql :=和=的区别
:=和=的区别 = 只有在set和update时才是和:=一样,赋值的作用,其它都是等于的作用.鉴于此,用变量实现行号时,必须用:= := 不只在set和update时时赋值的作用,在select也是 ...
- FORTIFY_SOURCE
In recent years Linux distributions started treating security more seriously. Out of many security f ...
- 64位CentOS6.5下Eclipse用Java连接mysql
1.到官网上下载jdbc驱动,我下载的是mysql-connector-java-5.0.8.tar.gz 2.解压下载到的文件 tar -zxvf mysql-connector-java-5.0. ...
- hdu_1005_Number Sequence_201310222120
Number Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 移动端 javascript 计算html font-size
直接上代码 (function(doc, win) { var docEl = doc.documentElement, resizeEvt ...
- 开源GIS软件 4
空间数据操作框架 Apache SIS Apache SIS 是一个空间的框架,可以更好地搜索,数据聚类,归档,或任何其他相关的空间坐标表示的需要. kvwmap kvwmap是一个采用PHP开发的W ...
- 将XML文件转化成NSData对象
NSData *xmlData = [[NSData alloc]initWithContentsOfFile:[NSString stringWithFormat:@"%@/People. ...
- object-c 不定參数的遍历和原理
object-c接收随意类型的參数: /** * 接收String类型的多个參数 * @param firsParam 第一个參数 */ -(void)TestString:(NSString*)fi ...