ImageVerifierCode 换一换
格式:DOCX , 页数:43 ,大小:442.95KB ,
资源ID:27118695      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/27118695.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(c++学习笔记.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

c++学习笔记.docx

1、c+学习笔记函数对象1.函数对象的定义/声明一个普通的类并重载“()”操作符:class Negatepublic:int operator() (int n) return -n; 重载操作语句中,记住第一个圆括弧总是空的,因为它代表重载的操作符名;第二个圆括弧是参数列表。一般在重载操作符时,参数数量是固定的,而重载“()”操作符时有所不同,它可以有任意多个参数。2.使用函数对象#include using std:cout;void Callback(int n, Negate & neg)int val = neg(n); /调用重载的操作符“()”cout val;/注意neg是对象,

2、而不是函数。编译时,编译器将语句int val = neg(n);转化为int val = neg.operator()(n);通常,函数对象不定义构造函数和析构函数。因此,在创建和销毁过程中就不会发生任何问题。前面曾提到过,编译器能内联重载的操作符代码,所以就避免了与函数调用相关的运行时问题。/为了完成上面个例子,我们用主函数main()实现Callback()的参数传递:int main()Callback(5, Negate() ); /输出 -5本例传递整数5和一个临时Negate对象到Callback(),然后程序输出-5。3.编写模板函数对象从上面的例子中可以看出,其数据类型被限制

3、在int,而通用性是函数对象的优势之一,如何创建具有通用性的函数对象呢?方法是使用模板,也就是将重载的操作符“()”定义为类成员模板,以便函数对象适用于任何数据类型:如double,_int64class GenericNegatepublic:template T operator() (T t) const return -t;int main()GenericNegate negate;cout negate(5.3333); / doublecout negate(10000000000i64); / _int644.标准库中函数对象C+标准库定义了几个有用的函数对象,它们可以被放到S

4、TL算法中。例如,sort()算法以判断对象(predicate object)作为其第三个参数。判断对象是一个返回Boolean型结果的模板化的函数对象。可以向sort()传递greater或者less来强行实现排序的升序或降序:#include / for greater and less#include /for sort()函数对象用于求最大值#include #include #include using namespace std;template const Object & findMax(const vector & arr, Comparator cmp)/求最大值 int

5、 maxIndex = 0; for (int i = 1; i arr.size(); i+) if (cmp.isLessThan(arrmaxIndex, arri) /此时的isLessThan还不知道具体的定义,要看cmp到底是什么maxIndex = i; /maxIndex每次取到的都是i值,而且只有当arrmaxIndexarri时才会更新maxIndex的值,可知arrmaxIndex记录的是最大值 return arrmaxIndex; class CaseInsensitiveComparepublic: /true: lhsrhs bool isLessThan(con

6、st string & lhs, const string & rhs) const return _stricmp(lhs.c_str(), rhs.c_str() 0;/使用string的成员函数,不区分大小写 /return lhs rhs;/使用string的函数,区分大小写 ;int main() vector arr(4); arr0 = ZEBRA; arr1 = zebrc; arr2 = zebrf; arr3 = zebrd; cout findMax(arr, CaseInsensitiveCompare() vir();/运行错误虚函数实现多态#include usin

7、g namespace std;class Fatherpublic: virtual void vir() cout 父类的vir()函数被执行 endl; ;class Son : public Fatherpublic: void vir() cout 子类的vir()函数被执行 vir(); /父类的vir()函数被执行 pf = new Son; /子类对象赋值给父类指针,也可以通过&s赋值 pf-vir(); /子类的vir()函数被执行 return 0;1.子类对象可以赋值给父类指针(可以通过取地址或者new赋值)2.父类对象不可以赋值给子类指针,因为子类指针很可能访问到父类没

8、有的一些属性及函数,会出错3.对于纯虚基类,不能创建对象,也不能使用new,只能创建指针,但只能将子类对象赋值给这个基类指针;因而纯虚基类的指针也只能访问子类的同名虚函数。C+中不能重载为友元函数的四个运算符C+规定有四个运算符=, -, , ()不能重载为友员函数,只能重载为类的非静态成员函数初始化和赋值的区别拷贝构造函数和赋值构造函数1. 初始化:对于一个类A a对象,初始化发生在定义a时,比如A a(7) 或A a =7;都叫初始化,都是调用自己定义的构造函数2. 赋值:给已经存在了的对象赋值,如A a; a=7;3. 拷贝构造函数首先是一个构造函数,同样没有返回值,也是用来构造一个对象

9、的,只不过参数是一个类对象,即用一个对象构造一个新对象4. 赋值构造函数是把一个对象赋值给一个原有的对象,所以如果原来的对象中有内存分配要先把内存释放掉,而且还要检查一下两个对象是不是同一个对象,如果是的话就不做任何操作。而且需要返回一个对象自身的引用(这必定要调用拷贝构造函数),以便赋值之后的操作下面分两种情况讨论一段代码a.重载了赋值运算符#include using namespace std;class Apublic: A() x = 99; cout Call A() endl; A(int xx) cout Call A(int xx) endl; x = xx; A(A &a)

10、 x = a.x; cout 拷贝构造函数被调用 endl; A operator=(A a) /赋值构造函数被调用 x = a.x; cout 赋值构造函数被调用 endl; return *this; A operator=(int xx) /重载赋值运算符 cout 重载赋值运算符被调用 endl; x = xx; return *this; private: int x;int main() A a; /调用默认构造函数 a = 7;/由于重载了上述赋值运算符,故调用赋值运算符,在赋值运算符内又调用了拷贝构造函数 A b(a);/调用拷贝构造函数 system(pause); retu

11、rn 0;输出结果:b.没有重载赋值运算符#include using namespace std;class Apublic: A() x = 99; cout Call A() endl; A(int xx) cout Call A(int xx) endl; x = xx; A(A &a) x = a.x; cout 拷贝构造函数被调用 endl; A operator=(A a) /赋值构造函数被调用 x = a.x; cout 赋值构造函数被调用 endl; return *this; private: int x;int main() A a; /调用默认构造函数 a = 7;/由

12、于没有重载了上述赋值运算符,故先调用构造函数创建一个临时对象,再调用赋值构造函数,在赋值构造函数内又调用了拷贝构造函数 A b(a);/调用拷贝构造函数 system(pause); return 0;输出结果:c+中#include中函数列表 using :abs; /绝对值 using :acos; /反余弦 using :acosf; /反余弦 using :acosl; /反余弦 using :asin; /反正弦 using :asinf; /反正弦 using :asinl; /反正弦 using :atan; /反正切 using :atan2; /y/x的反正切 using :

13、atan2f; /y/x的反正切 using :atan2l; /y/x的反正切 using :atanf; /反正切 using :atanl; /反正切 using :ceil; /上取整 using :ceilf; /上取整 using :ceill; /上取整 using :cos; /余弦 using :cosf; /余弦 using :cosh; /双曲余弦 using :coshf; /双曲余弦 using :coshl; /双曲余弦 using :cosl; /余弦 using :exp; /指数值 using :expf; /指数值 using :expl; /指数值 usi

14、ng :fabs; /绝对值 using :fabsf; /绝对值 using :fabsl; /绝对值 using :floor; /下取整 using :floorf; /下取整 using :floorl; /下取整 using :fmod; /求余 using :fmodf; /求余 using :fmodl; /求余 using :frexp; /返回value=x*2n中x的值,n存贮在eptr中 using :frexpf; /返回value=x*2n中x的值,n存贮在eptr中 using :frexpl; /返回value=x*2n中x的值,n存贮在eptr中 using :

15、ldexp; /返回value*2exp的值 using :ldexpf; /返回value*2exp的值 using :ldexpl; /返回value*2exp的值 using :log; /对数 using :log10; /对数 using :log10f; /对数 using :log10l; /对数 using :logf; /对数 using :logl; /对数 using :modf; /将双精度数value分解成尾数和阶 using :modff; /将双精度数value分解成尾数和阶 using :modfl; /将双精度数value分解成尾数和阶 using :pow;

16、 /计算幂 using :powf; /计算幂 using :powl; /计算幂 using :sin; /正弦 using :sinf; /正弦 using :sinh; /双曲正弦 using :sinhf; /双曲正弦 using :sinhl; /双曲正弦 using :sinl; /正弦 using :sqrt; /开方 using :sqrtf; /开方 using :sqrtl; /开方 using :tan; /正切 using :tanf; /正切 using :tanh; /双曲正切 using :tanhf; /双曲正切 using :tanhl; /双曲正切 usin

17、g :tanl; /正切int abs(int i); / 处理int类型的取绝对值double fabs(double i); /处理double类型的取绝对值float fabsf(float i); /处理float类型的取绝对值C+运算符重载1.怎么实现运算符的重载?方式:类的成员函数 或 友元函数(类外的普通函数)规则:不能重载的运算符有 . 和 .* 和 ?: 和 : 和 sizeof友元函数和成员函数的使用场合:一般情况下,建议一元运算符使用成员函数,二元运算符使用友元函数如果+作为后缀使用,则需要一个额外的参数,用于和前缀区分开一元运算符作为成员函数,0个参数;作为友元函数,1

18、个参数二元运算符作为成员函数,1个参数;作为友元函数,2个参数 1、运算符的操作需要修改类对象的状态,则使用成员函数。如需要做左值操作数的运算符(如=,+=,+)2、运算时,有数和对象的混合运算时,必须使用友元3、二元运算符中,第一个操作数为非对象时,必须使用友元函数。如输入输出运算符具体规则如下:运算符建议使用所有一元运算符成员函数 ( ) - 必须是成员函数+= -= / = *= = &= != %= = = , 似乎带等号的都在这里了.成员函数所有其它二元运算符, 例如: , +, *, / , %友元函数必须是友元函数2.-运算符的重载-操作符看起来像二元操作符:接受一个对象和一个成

19、员名。但是,其实箭头操作符是一元操作符。况且-的右操作数不是表达式。如何开始:由a开始,分下面两种情况1、a是指针,那么就是我们熟悉的,指向我们a类型的成员数据或函数“b”;到这里,就结束了!2、a是对象,那么a必须有成员函数operator-(否则会报错)。那么就调用a的operator-函数。由于operator-返回的可能是指针,也可能是对象,那么就又进入了下一轮递归:是指针还是对象,走1或2,如此递归。如何结束:不管a是指针或者对象,最终都是走到指针结束(当然,写错了也走不下去)。代码#include using namespace std;class Apublic: void ac

20、tion() cout Action in class A! () return &a; void action() cout Action in class B! () return b; void action() cout Action in class C! action(); C c; c-action(); getchar(); return 0;代码分析C* pc = new C;pc-action();输出的结果是Action in class C!这个结果比较好理解,pc是类对象指针,此时的箭头操作符使用的是内置含义,故pc直接调用其成员函数action。而下面的代码C c;

21、c-action();输出的结果是Action in class A!其实c-action()的含义与c.operator-().operator-()-action();相同。c是对象,c后面的箭头操作符使用的是重载箭头操作符,即调用类C的operator-()成员函数,此时返回的是类B的对象。所以接着调用类B的operator-()成员函数,此时返回的是类A的指针。最终由A的指针调用A的action()成员函数。注释:这里存在一个递归调用operator-()的过程,直到最后使用了一次内置含义的箭头操作符。参考博客: 两个整数相除保留两位小数inta=100;intb=3;floatc=(

22、float)a/(float)b;Stringaa=FormatFloat(0.00,c);c语言 二维数组a【0】与a与a【0】【0】有什么区别?数组在内存中是连续按行分布的,对于a23=1,2,3,4,5,6;它在内存中的分布式1,2,3,4,5,6;所以他等价于a23=1,2,3,4,5,6;在c/c+中,数组名也即是数组首地址,这里加入a=0x1000;那么它的地址分就是:1000,1004,1008,100c,1010,1014;&a00也就取第一个元素的地址,即1000,a0是第一行1000,1004,1008的首地址,也是1000,也即是a元素的首地址;int *b=a0;*b和

23、a0是等的,是a数组第一行首地址;不同的是a0是只读的,*b是可读写的因为b是指针变量,你可以试试a03,a04,a05都能打印出来,别看a23以为这样越界了,其实越不越界是按地址来算的,地址上讲,&a03=a1,所以完全没问题;按照地址计算上面打印的值就是4,5,6;同理用*(b+3),*(b+4),*(b+5)也是一样的道理;a就是数组的首地址,a0是第一行第一个元素的首地址,也即是a的首地址,&a0是第一行的首地址,从数值上讲,没问题,只是数据类型上不一样;a00就是取第一行第一个元素的值,也即是1int变量转换成二进制#include #include using namespace

24、std; int a =-2; int b = 4; /cout static_castbitset (a)endl;/转换成32位的二进制 cout (a&b) endl;Char*指针与char数组#include#includeusing namespace std;int main() char a6 = hello; cout static_cast(a) endl; cout static_cast bitset (int)(a) endl; cout (void*)(a + 1) endl; cout static_cast bitset (int)(a + 1) endl; char *p = NULL; p = a; cout p endl; string s = hello; cout (void*)&s0 endl; cout (void*)&s1 endl; return 0;注意:1、&a表示的是指针变量a的地址,a表示的是数组的首地址,两者数值上相同。2、用cout输出a,要通过(void*)进行转换,转换之后输出的是16进制的地址;用(int)转换,输出的是十进制数值。一个字符如a,占一个字节,由8位二进制组成。指针每自增1,由于字符只占一个字节,所以指针在寻址的时候就是一个字节的寻址,数值上只增加100010100是一

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1