已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C+高质量编程总结3R1:指针参数是如何传递内存的? 看下面的例子void GetMemory(char* p, int num)p = (char*) malloc( num * sizeof(char) ) ;void Test(void)char *str = NULL ;GetMemory(str, 100) ;/ 执行完后,str仍然为NULLstrcpy(str, hello) ;/ 运行错误问题:编译器总是要为函数的每个参数制作临时副本,指针参数p的临时副本是_p,编译器使得_p = p,如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫没有变。 如果非要达到“用指针来申请内存”的目的,可以这样:void GetMemory(char *p, int num)*p = (char*) malloc( num* sizeof(char) ) ;. 由于指向指针的指针这个概念不号理解,我们可以利用函数的返回值来返回申请的地址char* GetMemory(int num)char *p = (char*) malloc( num * sizeof(char) ) ;return p ; 注意把上面的例子和下面的例子作比较/ 这样是完全正确的,返回的是内存中堆的地址char* GetMemory(int num)char *p = (char*) malloc( num* sizeof(char) ) ;return p ;/ 这样返回就错了,原因是函数返回了一个指向 栈内存 的指针char * GetMemory()char *p = Hello ;return p ;/ 总结:在函数中返回 堆地址 是可以的,但是返回 栈地址 是不正确的 2:有了malloc/free之后为什么还要用new/delete ? 对于非对象数据类型,这两个是等价的 对于对象就不一样了 malloc/free是系统函数,不是运算符,它们不能进行对象的构造和析构 free/delete是运算符,可以进行对象的析构和构造 注意: 用free来释放new创建的对象,程序可能会出现问题 用delete来释放malloc创建的内存,理论上不会出现问题,但是程序的可读性不强 3:对一个指针释放两次会出现问题例如:下面是错误的:-int *p = new int100 ;delete p ;delete p ; 4:注意数据类型的隐式转换带来的问题例如,下面的程序:-void Fun(int num) cout Number : num endl ; void Fun(float num) cout Number : num endl ; int main()double d_Num = 1.2 ;Fun(d_Num) ;/ 编译错误:调用的函数不明确return 0 ; 5:继承中的重载,隐藏和覆盖 重载比较好区别,在这里主要比较隐藏和覆盖 覆盖只有一种情况: 基类和派生类的函数名称相同 函数的参数相同 其余的情况是隐藏: 函数名称相同,参数不同时,不论有没有virtual关键字,都是隐藏 函数名称相同,参数不同时,但是没有virtual关键字,是隐藏由此可见,隐藏和覆盖的重要一个区别就是有没有virtual关键字举例,看下面的程序:#include class Basepublic:virtual void f(float x) cout Base:f(float) x endl; void g(float x) cout Base:g(float) x endl; void h(float x) cout Base:h(float) x endl; ;class Derived : public Basepublic:virtual void f(float x) cout Derived:f(float) x endl; void g(int x) cout Derived:g(int) x endl; void h(float x) cout Derived:h(float) x endl; ;在上面的例子中函数f是覆盖函数g是隐藏函数h是隐藏 6:函数重载和运算符重载的不同点 函数调用时,参数出现圆括号内 对于运算符,参数出现在其左右两侧例如:c = Add(a, b) ;c = a + b ; 7:关于重载运算符的一些问题 如果运算符被重载为全局函数,那么一元运算符有一个参数,二元运算符有两个参数 如果运算符被重载为成员函数,那么一元运算符没有参数,二元运算符只有一个参数 不要过分担心自己不会用,运算符重载实质上是函数 不要过度热心的使用,在它可以使代码变得更容易懂时,才能用 8:内联关键字的所在地 一定要放在定义的地方 在声明的地方多放一个也许可以 inline:定义时的关键字 const:声明和定义都要的关键字 默认值:声明时要,定义时不要的关键字 9:一个类中缺省的函数 对于任何一个类,如何程序员不写任何函数,系统会自动生成以下四个函数:A(void);/ 缺省的无参构造函数A(const A &a) ;/ 缺省的拷贝构造函数A(void) ;/ 缺省的析构函数A& operator=(const A &a)/ 缺省的赋值函数 注意:拷贝构造函数和赋值函数时完全两个不同的函数10:列表方式的初始化的时间问题发生在函数体中的任何代码执行之前11:可不可以人工调用基类的构造函数? 完全可以的 因为调用构造函数的顺序时这样的,现调用基本的,再调用派生类的,所以必须使用初始化列表的方法来调用,调用的方法如下:class2(int No1, int No2) : class1(No1) m_No2 = No2 ; ,只有这样才可以保证基类的构造函数先调用12:类的两种初始化方式的效率: 对于内部数据类型,两种方式效率相同 对于非内部数据类型,应该采用初始化列表方式初始化,这样效率高些-class Bpublic:B(A &a) : m_a(a) private:A m_a; ;class Bpublic:B(A &a) m_a = a ; private:A m_a ;比较: 上面的初始化时字节调用“拷贝构造函数”,这样效率比较高 下面的初始化分为两个步骤: 创建A对象 用赋值函数来进行赋值13:类的数据成员初始化的顺序 只和类声明时的顺序有关 原因:这样保证了析构函数的唯一性14:含有指针的类的默认构造函数易出现的问题:造成两个指针指向同一块内存,这样容易出现的问题时: 一方改变时,另一方也同时改变 释放内存时,内存被释放了两次,程序容易出现问题15:拷贝构造函数和赋值函数的推荐写法: 拷贝构造函数:A a = A(b) ;/ 这样看起来比较象个构造函数 赋值函数:A a = b ;/ 这样看起来更有赋值的意义16:举例说明拷贝构造函数和赋值函数:/-String类的完整代码-class Stringpublic:String(const char *str=NULL) ;/ 构造函数String(const String& str) ;/ 拷贝构造函数String() ;/ 析构函数String& operator =(const String &str) ; / 赋值函数private:char *m_data ; ;String:String(const char *str)/ 构造函数if (str = NULL)m_data = new char1 ;m_data = 0 ;elsem_data = new charstrlen(str)+1 ;strcpy(m_data, str) ;String:String()/ 析构函数delete m_data ;String:String(const String &str)/ 拷贝构造函数m_data = new charstrlen(str.m_data)+1 ;strcpy(m_data, str.m_data) ;String& String:operator =(const String &str) / 赋值函数if (this = &str)/ 如果时自我赋值return *this ;delete m_data ;/ 删除旧的空间m_data = new charstrlen(str.m_data)+1 ;strcpy(m_data, str.m_data) ;return *this ;17:继承的注意点基类的构造函数(包括拷贝构造函数),析构函数,赋值函数都不会被派生类继承18:因为基类的构造函数,析构函数,赋值函数都不会被派生类继承,所以如果类之间有派生关系时,一定要注意: 派生的构造函数应在其初始化列表中调用基类的构造函数 基类和派生类的析构函数应该声明为virtual-演示程序代码-#include using namespace std ;class Basepublic:Base(int i=1, int j=2, int k=3) ;virtual Base() ;Base(const Base &other) ;Base& operator =(const Base &other) ;private:int m_I ;int m_J ;int m_K ; ;Base:Base(int i, int j, int k)/ 基类的构造函数m_I = i ;m_J = j ;m_K = k ;Base:Base()/ 基类析构函数Base:Base(const Base &other)/ 基类拷贝构造函数m_I = other.m_I ;m_J = other.m_J ;m_K = other.m_K ;Base& Base:operator =(const Base &other)/ 基类赋值函数if (this = &other)return *this ;m_I = other.m_I ;m_J = other.m_J ;m_K = other.m_K ;return *this ;class Driver : public Basepublic:Driver(int i=4, int j=5, int k=6, int a=7, int b=8, int c=9) ;Driver(const Driver &other) ;Driver() ;Driver& operator =(const Driver &other) ;void Print() const ;private:int m_A ;int m_B ;int m_C ; ;Driver:Driver(int i, int j, int k, int a, int b, int c) : Base(i,j,k) / 调用基类构造函数m_A = a ;m_B = b ;m_C = c ;Driver:Driver(const Driver &other) : Base(other)/ 调用基类拷贝构造函数m_A = other.m_A ;m_B = other.m_B ;m_C = other.m_C ;Driver:Driver()Driver& Driver:operator =(const Driver &other)if (this = &other)return *this ;Base:operator =(other) ;/ 调用基类赋值函数m_A = other.m_A ;m_B = other.m_B ;m_C = other.m_C ;return *this ;19:什么情况下继承:若在逻辑上B是A的一种,那么允许继承例如:human - man - boy20:函数返回值值是引用的情况: 函数返回值是引用的情况不多 好像只出现在类的赋值函数中,作用是为了实现链式表达21:注意static成员占用的不是类的空间cout sizeof(class_Name) ;/ 输出的是所有的非sttic成员总的空间22:为了防止重复编译,应该这样作:#ifndef XXXX.H#define XXXX.H.#endif23:一个程序在内存中的分布: 数据静态数据存储区动态数据存储区堆栈存储区 可执行程序区24:指向 数组 的指针例如:int i; int arr10 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ; int (*p)10 = &arr ; for(i=0;i10;i+) printf(%4d,(*p)i);=int (*p)10 = &arr ;/ 声明p是一个指向 有10个整数数组 的指针则,(*p)指的就是这个数组:(*p)1, (*p)2 ;指的就是它的元素25:数组名的两层含义: 是一个const指针 代表整个数组-例如:int (*p)10 = &array ;/ &array 就是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- C语言试题选择题及答案
- 2025年安全员B证考试试题及参考答案详解【巩固】
- 2025年卫生事业管理模拟真题卷
- 三类人员安全员C证继续教育考试题库
- 宜宾职业技术学院高职单招测试题(含答案解析)
- 2022年11月屏东县直遴选面试真题带题目详解
- 2025年电工中级职业技能考试电工仪表维护试题卷
- 2025年一级建造师《项目管理》模拟试题第四套
- 山西省税务师考《涉税服务实务》:增值税考试试卷
- 2025年考研计算机408科目真题汇编与模拟试卷
- BOPP项目可行性研究报告
- 收割机收割协议合同范本
- 重晶石精深加工生产线项目可行性研究报告
- 八年级语文上册统编版第六单元 课外古诗词诵读(公开课一等奖创新教学设计)
- 泌尿外科教学病例讨论
- 中华人民共和国两用物项出口管制条例考试试卷试题及参考答案
- 监理加盟合同协议书范本
- 2025年综合类-热力司炉工考试-高级热力司炉工历年真题摘选带答案(5卷单选一百题)
- 公司区域协同管理办法
- 架子鼓教学基础课件
- 第2课时四分位数与箱线图
评论
0/150
提交评论