C++类声明和成员函数定义的分离

类声明和成员函数定义的分离

       如果一个类只被一个程序使用,那么类的声明和成员函数的定义可以直接写在程序的开头。但是,如果一个类被多个程序使用,这样做的重复工作量就很大了,效率就太低了。在面向对象的程序开发中,一般做法就是将类的声明(其中包含成员函数的声明)放在指定的头.h文件中,用户如果想用该类,只要把有关的.h头文件包含进来即可,不必在程序中重复书写类的声明,提高编程的效率。

       在.h头文件中对类进行声明。那么,对类函数的定义,可以放在源文件中。C++中的源文件是以.cpp为后缀的文件。例如 test.cpp这样的文件名。

       所以,对类成员函数的定义一般不放在头文件中,而放在源文件中。例如,可以分别写这两个文件:

(1) 定义头文件

//student.h --- 这是头文件,在此文件中进行类的声明

 

(2) 定义源文件

//student.cpp --- 在此文件中进行函数的定义

(3) 调用类的源文件

//main.cpp --- 主函数模块

       这是一个包含3个文件的程序,组成两个文件模块:一个是主模块main.cpp,一个是student.cpp。在主模块中又包含头文件student.h。

请注意:由于将头文件 student.h放在用户当前目录中,因此,在文件名两侧用双撇号包起来(”student.h”),如果使用尖括号包含头文件,编译器会认为student.h头文件系统定义的头文件,就到系统的目录下查找该文件。编译时会找不到此文件。

       编译运行程序如下:

       可以看到,通过g++编辑器,编译student.cpp、main.cpp文件。得到目标文件out程序。然后,执行out程序。

注意:C++规定,在包含头文件的时候,使用尖括号< >包含的是系统定义的头文件,使用双引号“”,则包含的是用户自己定义的头文件。

       在执行主函数时调用stud中的print()函数,输出各个成员变量的值。

总结

本章节我们学习了C++类对象的定义和使用。C++类定义对象,可以通过3种方式访问对象的成员,如下:

  1. 对象是普通变量,通过成员运算符“点号”;
  2. 对象是指针类型,通过指针运算符,以指针的方式访问成员;
  3. 对象是引用类型,通过成员运算符“点号”;

在定义C++类的时候,我们需要考虑信息的封装和隐藏,所以,可以把C++类的声明和成员函数的定义分离,定义在不同的.h头文件和.cpp源文件中。这样合理的地规划C++类的代码分离,可以有效地管理C++的代码。

读者要仔细分析,掌握好每一个知识点,然后,自己总结出对该知识点的理解。自己总结出来的知识,理解才深刻,才是自己掌握的知识。

韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++ 编程思想,绝对清晰,物超所值!!! 目 录 译者序 前言 第1章 对象的演化 1 1.1 基本概念 1 1.1.1 对象:特性+行为 1 1.1.2 继承:型关系 1 1.1.3 多态性 2 1.1.4 操作概念:OOP程序像什么 3 1.2 为什么C++会成功 3 1.2.1 较好的C 3 1.2.2 采用渐进的学习方式 4 1.2.3 运行效率 4 1.2.4 系统更容易表达和理解 4 1.2.5 “库”使你事半功倍 4 1.2.6 错误处理 5 1.2.7 大程序设计 5 1.3 方法学介绍 5 1.3.1 复杂性 5 1.3.2 内部原则 6 1.3.3 外部原则 7 1.3.4 对象设计的五个阶段 9 1.3.5 方法承诺什么 10 1.3.6 方法应当提供什么 10 1.4 起草:最小的方法 12 1.4.1 前提 13 1.4.2 高概念 14 1.4.3 论述(treatment) 14 1.4.4 结构化 14 1.4.5 开发 16 1.4.6 重写 17 1.4.7 逻辑 17 1.5 其他方法 17 1.5.1 Booch 18 1.5.2 责任驱动的设计(RDD) 19 1.5.3 对象建模技术(OMT) 19 1.6 为向OOP转变而采取的策略 19 1.6.1 逐步进入OOP 19 1.6.2 管理障碍 20 1.7 小结 21 第2章 数据抽象 22 2.1 声明定义 22 2.2 一个袖珍C库 23 2.3 放在一起:项目创建工具 29 2.4 什么是非正常 29 2.5 基本对象 30 2.6 什么是对象 34 2.7 抽象数据型 35 2.8 对象细节 35 2.9 头文件形式 36 2.10 嵌套结构 37 2.11 小结 41 2.12 练习 41 第3章 隐藏实现 42 3.1 设置限制 42 3.2 C++的存取控制 42 3.3 友元 44 3.3.1 嵌套友元 45 3.3.2 它是纯的吗 48 3.4 对象布局 48 3.5 48 3.5.1 用存取控制来修改stash 50 3.5.2 用存取控制来修改stack 51 3.6 句柄(handle classes) 51 3.6.1 可见的实现部分 51 3.6.2 减少重复编译 52 3.7 小结 54 3.8 练习 54 第4章 初始化与清除 55 4.1 用构造函数确保初始化 55 4.2 用析构函数确保清除 56 4.3 清除定义块 58 4.3.1 for循环 59 4.3.2 空间分配 60 4.4 含有构造函数和析构函数的stash 61 4.5 含有构造函数和析构函数的stack 63 4.6 集合初始化 65 4.7 缺省构造函数 67 4.8 小结 68 4.9 练习 68 第5章 函数重载与缺省参数 69 5.1 范围分解 69 5.1.1 用返回值重载 70 5.1.2 安全型连接 70 5.2 重载的例子 71 5.3 缺省参数 74 5.4 小结 81 5.5 练习 82 第6章 输入输出流介绍 83 6.1 为什么要用输入输出流 83 6.2 解决输入输出流问题 86 6.2.1 预先了解操作符重载 86 6.2.2 插入符与提取符 87 6.2.3 通常用法 88 6.2.4 面向行的输入 90 6.3 文件输入输出流 91 6.4 输入输出流缓冲 93 6.5 在输入输出流中查找 94 6.6 strstreams 96 6.6.1 为用户分配的存储 96 6.6.2 自动存储分配 98 6.7 输出流格式化 100 6.7.1 内部格式化数据 101 6.7.2 例子 102 6.8 格式化操纵算子 106 6.9 建立操纵算子 108 6.10 输入输出流实例 111 6.10.1 代码生成 111 6.10.2 一个简单的数据记录 117 6.11 小结 123 6.12 练习 123 第7章 常量 124 7.1 值替代 124 7.1.1 头文件里的const 124 7.1.2 const的安全性 125 7.1.3 集合 126 7.1.4 与C语言的区别 126 7.2 指针 127 7.2.1 指向const的指针 127 7.2.2 const指针 127 7.2.3 赋值和型检查 128 7.3 函数参数和返回值 128 7.3.1 传递const值 128 7.3.2 返回const值 129 7.3.3 传递和返回地址 131 7.4 133 7.4.1 里的const和enum 133 7.4.2 编译期间里的常量 134 7.4.3 const对象和成员函数 136 7.4.4 只读存储能力 139 7.5 可变的(volatile) 140 7.6 小结 141 7.7 练习 141 第8章 内联函数 142 8.1 预处理器的缺陷 142 8.2 内联函数 144 8.2.1 内部的内联函数 145 8.2.2 存取函数 146 8.3 内联函数和编译器 150 8.3.1 局限性 150 8.3.2 赋值顺序 150 8.3.3 在构造函数和析构函数里隐藏行为 151 8.4 减少混乱 152 8.5 预处理器的特点 153 8.6 改进的错误检查 154 8.7 小结 155 8.8 练习 155 第9章 命名控制 157 9.1 来自C语言中的静态成员 157 9.1.1 函数内部的静态变量 157 9.1.2 控制连接 160 9.1.3 其他的存储型指定符 161 9.2 名字空间 161 9.2.1 产生一个名字空间 162 9.2.2 使用名字空间 163 9.3 C++中的静态成员 166 9.3.1 定义静态数据成员的存储 166 9.3.2 嵌套和局部 168 9.3.3 静态成员函数 169 9.4 静态初始化的依赖因素 171 9.5 转换连接指定 174 9.6 小结 174 9.7 练习 174 第10章 引用和拷贝构造函数 176 10.1 C++中的指针 176 10.2 C++中的引用 176 10.2.1 函数中的引用 177 10.2.2 参数传递准则 178 10.3 拷贝构造函数 179 10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针
1、抽象与操作符重载 定义表示形状的抽象及相应的派生,并实现相关操作符重载。 (1)定义表示形状的抽象Shape: 添加公有成员函数double Area(),用于计算形状面积;定义为纯虚函数; 添加公有成员函数void Show(),用于显示形状信息,定义为纯虚函数; 定义虚的析构函数; 重载比较操作符:==、>和<,用于比较两个形状面积的大小关系,返回值型为bool,可以定义成员函数或友元函数。 、、、、、、 2、虚函数 利用虚函数实现多态: (1)设计Person,要求具有用于表示姓名的保护数据成员:string szName; 实现信息打印的公有成员函数:void Print()。其中,Print函数设计为虚函数,输出的信息格式为:“Person 姓名”。 、、、、、、 3、操作符重载 定义有理数(分母不为0的分数,分子分母均为整数)Rational,实现相应操作符的重载。 (1)定义私有数据成员:分子int iUp; 分母 int iDown。 (2)定义私有成员函数:void Reduce() 和 int Gcd(int l, int r),分别用于有理数的约简和求两个整数的最大公约数。其中,在约简时需要求取分子与分母的最大公约数。 、、、、、、 4、记录文件的读写操作 源数据文件(文本格式)中包含有每个学生的记录:ID(身份识别号)、 Gender(性别)、 Birthday(生日)和EnrollmentDate(入学时间),字段之间以半角逗号分隔,记录之间以换行符分隔。要求从源数据文件中读取学生记录并删除重复记录,然后根据ID大小对所有记录按从小到大排序,将排序后的记录保存到目标文件中并同时输出到屏幕上。 、、、、、、 5、简单文本文件的读写 、、、、、
C++中,的静态成员函数是属于本身而不是对象的成员函数。静态成员函数声明时使用了static关键字。静态成员函数在使用时可以直接通过名加作用域解析运算符::调用,而不需要通过对象来调用。 静态成员函数声明和实现可以分离,意味着可以将静态成员函数声明定义放在不同的文件中。这种分离的用途主要有两个方面: 第一,可以将静态成员函数声明放在的头文件中,将定义放在实现文件中,这样可以提高代码的可读性和可维护性,使得的接口部分和实现部分分离开来。 第二,当多个源文件需要使用同一个的静态成员函数时,可以将函数的声明放在一个公共的头文件中,而将函数的定义放在不同的源文件中,然后将这些源文件编译链接在一起。这样可以避免在多个源文件中重复定义静态成员函数,减少了代码的冗余,提高了编译的效率。 需要注意的是,静态成员函数定义时无法访问的非静态成员变量和非静态成员函数,因为静态成员函数没有this指针。但是静态成员函数可以访问的静态成员变量和静态成员函数。 总结起来,的静态成员函数声明实现分离可以提高代码的可读性、可维护性和代码复用性。它允许将的接口部分和实现部分分开,并使得多个源文件可以共享同一个的静态成员函数而不需要重复定义

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韦凯峰Linux编程学堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值