




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++知识C++对C的加Space实用性增struct类型C++中所有变量和函数都三目运算符增const增真正的枚C++对C的扩2.1概规inline默认参数和占位默认占位函数类和拷贝构造函数(copy初始化列运算符重重载规则双目运算符重单目运算符重输入输出运算符继承和派类和类之间的关继承的方派生类成员的标继承和组合并存,构造和析多继承与虚继多多态的概虚析构函重载、重写、重多态的原纯虚函数和抽象函数C对C分析以下三者的区别##include<string.h>#include<string>#include<cstring>通常情况下,如果有两个同名变量,一个是全局变量,另一个是局部变量,那么局部变量在其作用域内具有较高的优先权,它将全局变量。作用域运算符可以用来解决局部变量与全局变量的重名问题,即在局部变量的作用域内,可用:对被的同名的全局变量进行。inta10;//1.局部变量和全局变量同voidinta=//打印局部变量cout<<"局部变量a:"<<a<<//打印全局变量cout<<"全局变量a:"<<::a<<}命名空间的三种格式stdstd::cout<<std::hex<<3.4<<使用using指using可使得指定的标识符可用usingusingstd::cout;usingstd::endl;usingstd::cin;使用usingnamespacestd;整个空间using编译指令使整个命名空间标识符可#define_CRT_SECURE_NO_WARNINGS#include<iostream>usingnamespacenamespace{inta=100;intb=10;namespaceB{inta=50;intb=5;}}namespace{inta=50;intb=5;}void{cout<<A::a<<}void{usingA::B::b;cout<<b<<endl;}void{usingnamespacecout<<a<<"\t"<<b<<}int{}usingnamespace三种有命名空间最简便的方法就是使用using编译指令, 这样把stdusingnamespace中的所有变量都解放出来,就像使用全局变量一样。但不建议使用sing编译指令,如果局部有同名函数和变量,则会覆盖,使用sing则不会,如果有同名会报错.C语言中的变量都必须在作用域开始的位置定义!!(C99已经支持在随意位置定义)在C语言中,重复定义多个同名的全局变量是合法的,C不允许重复定义多个同名的全局变量。C语言中多个同名的全局变量最终会被到全局数据区的同一个地址空间上,如:##include<stdio.h>intg_var;intg_var=intmain(intargc,char{printf("g_var=%d\n",g_var);return0;}struct语言的srct定义了一组变量的集合,编译器并不认为这是一种新的类型,C中的src是一个新类型的定义。##define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include{charname[64];intage;int{ return0;}思考:C语言中的struct和C++中的struct的区别#include<stdio.h>#include<stdlib.h>#include<string.h>{printf("i=%d\n",}{return}int{printf("func2() %d\n",func(1,2,3,4,return}以上代码在C语言编译器中是可以运行的,但在C语言编译器中不能运行。intf;表示返回值为int,接受任意参数的函数intf(void);表示返回值为int的无参函数在C++intf和intf(void)具有相同的意义,都表示返回值为int的无参函数中新增了bol类型关键字,只有true和fas两个值,理论上bol只占个字节,如果多个boo变量定义在一起,可能会个占1个t,这取决于编译器的实现,ru代表真值,编译器内部用1来表示,fse代表非真值,编译器内部用0表示,boo类型只有rue(非0)和fse(0)两个值,C编译器会在赋值时将非0值转换为rue,0值转换为fse。##include<iostream>usingnamespaceintmain(intargc,char{intboolb=printf("b=%d,sizeof(b)=%d\n",b,sizeof(b));b=4;a=printf("a=%d,b=%d\n",a,b);b=-4;a=printf("a=%d,b=%d\n",a,a=b=printf("a=%d,b=%d\n",a,b);b=0;printf("b=%d\n",return}三目运算符:表达式1?表达式2:表达式3##include<stdio.h>#include<stdlib.h>intmain(void){inta=intb=20;//返回一个最小数,并且给最小数赋值为////(表达式1?表达式2:表达式3)当表达式2或者表达式3是一个常量的时候,(a<b?a:b)=printf("a=%d,b=%d\n",a,b);return}在C语言中不能编译通过三目运算符在C语言编译器中返回的是一个变量的值,如,上述代码返回值为0,对常量0进行赋值,自然出错,而在C语言编译器中返回的是“变量本身”—–内存空间地址,对其赋值,所以不会出错。##include<stdio.h>#include<stdlib.h>int{inta=intb=20;//返回一个最小数,并且给最小数赋值为//三目运算符是一个表达式,表达式*(a<b?&a:&b)=printf("a=%d,b=%d\n",a,b);//返回变量a的地址,对地址取值,可以对变量进行修改return}结论:三目运算符在C语言中返回变量的值,不能作为左值使用,但是可以用作右值,如intc=a<b?a:b注意:三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用,即表达式2或表达式量,不能作为左值。如:(a<b?1:b)=3;//错误当左值的条件:要有内存空[[左值和右值概念比如:inttemp=10;temp在内存中有地址,10没有,但是可以Read到它的constconstinta;intconst//第一个第二个意思一样代表一个常整形constint*c;intconst//第三 c是一个指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改int*const//第四 d常指针(指针变量不能被修改,但是它所指向内存空间可以被修改constint*conste//第五 e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改 修饰的常量的值##include<stdio.h>intmain(){constinta=10;int*p=(int*)&a;printf("a===>%d\n",*p=11;printf("a===>%d\n",a);return0;}C++中从const和#define的区别cost有作用域,而#dfin不重视作用域,默认定义处到文件结尾.如果定义在指定作用域下有效的常量,那么#dine就不能用。##include<iostream>voidfun1(){#definea10constintb=20;}void{printf("a=%d\n",//printf("b=%d\n",}int{return0;}c语言中枚举本质就是整型,枚举变量可以用任意整型赋值。而c++中枚举变量,只能用被枚举出来的元素初始例如##includeenumseason{SPR,SUM,AUT,WIN};intmain(){enumseasons=s=0;//error,但是C语言可以通过,在C++中不能通过printf("s=%d\n",s);s=SUM;printf("s=%d\n",s);return0;}变量名的本质是一段连续内变量名,本身是一段内存的,即别名(alias).可以看作一个已定的语法:Type&name=1)没有定义,是一种关系型。它和原有某一变量(实体)的系。故而类型与原类型保持一致,且不分配内存。与被的变量有相同的地3)可对,再次。多次的结果,是某一变量具有多个别名4)&符号前有数据类型时,是。其它皆为取地址////错误 类型不匹地址#define#include<iostream>#include<string>usingnamespacevoidswap_int(inta,int{inttem=a=b=}voidswap_ref(int&a,int{inttem=a=b=}voidswap_p(int*a,int{inttem=*a=*b=}//异或运算,只适用于int和charvoidswap1(int&a,int{//a=a^//b=a^//a=a^^=a^=b;}//加法运voidswap1(int&a,int{a=a+b=a-a=a-}int{inta=10;intb=swap_int(a,cout<<"aftersap_int(a,b):"<<"a="<<a<<"b="<<b<<endl;swap_p(&a,&b);cout<<"afterswap_p(&a,&b):"<<"a="<<a<<"b="<<b<<endl;swap_ref(a,b);cout<<"afterswap_ref(a,b):"<<"a="<<a<<"b="<<b<<endl;return0;}}//2.1.4//usingnamespaceintfunc1(){static=return}//返回变量,int&{static=return##include<iostream>structTeacher{intint{printf("sizeof(Teacher)%d\n",sizeof(Teacher));return0;}Type&name<===>Type*const2)C++编译器在编译过程中使用常指针作为的内部实现,因此所占2.1.6和指针的区a)创建的同时必须初始化,即必须一个具体的对象。指针创建的时候可以不必初始化b)不存在空,但是存在NULL指针c)在初始化之后,不可改变改变为其他对象,指针可以改变指向d)语言层面,的用法和对象一样;在二进制层面,一般都是通过指针来实现的inline 函数调用的开销。但是由于宏函数的处理发生在预处理阶段,缺失了语法和有可能带来的语意差错。C++中用内联函数inline函数实现代码真正的的内嵌。内联函数时nine关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。C++编译器直接将函数体插入在函数调用的地方内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)。内联函数由编译器处理,直接将编译后的函数体插入调用的宏代码片段由预处理器处理,进行简单的文本替换,没有任函数内联必须在调用语句之编译器对于内联函数的限制并不是,内联函数相对于普通函数的优势只是省去了函数调用时压栈,跳转和返回的开销。因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。在默认参数规则,如果默认参数出现,那么右边的都必须有floatfloatvolume(floatlength,floatweight=4,floathigh={return}int{floatv=volume(10);floatv1=volume(10,20);floatv2=volume(10,20,30);return}##include函数占位参占位参数只有参数类,有参数,一般情况下,在函数体内部无法使用占位参intfunc(inta,intb,int{returna+}int{func(1,2); 必须把最后一个占位参数补printf("func(1,2,3)=%d\n",func(1,2,return}可以将占位参数与默认参数结合起来使用;意义:为以后程序的扩展留下线索,兼容C语言程序中可能出现的不规范写法函数重载(FunctionOverload):用同一个函数名定义不同的函数,当函封装把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。类将成员变量和成员函数封装在类的内部,根据需要设置权限,通过成员函数管理内部状态。继承:继承所表达的是类之间相关的关系,这种关系使得对象可以继承另外一类对象的特征和能力。继承的作用:避免公用代码的重复开发,减少代码和数据冗余。多态:多态性可以简单地概括为“一个接口,多种方法”,字面意思为多种形态。程序在运行时才决定调用的函数,它是面向对象编程领域的概念。属对象对象公可可保可私可struct中所有行为和属性public的(默认)C++中的class可以指定行封装,可以达到,对内开放数据,对外数据,对外提供接口。达到了信息定义中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数.特点在对象生成的同时,自动调用,完成对象的初始化(变量赋值,对空间的申请)构造器与类名相同,无返回值。若果不自定义实现,系统提供一个无参,空构造器,一旦自定义,系统不再提供(不论使用哪一种一定要把无参的情况包含)定义中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数.特点拷贝构造函数(copy由己存在的对象,创建新对象。也就是说新对象,不由构造器来构造,构造器来完成。拷贝构造器的格式是固定的。格式:类名(const类名&与类名相同,无返回,const类型的本类如果没有自定义的话,系统提供了一个等位拷贝构造体(即浅拷贝,等位拷贝在没有对空间的情况下,介意满足需求,如果有堆空间的话,容易造成double)如果存在堆空间的话,需要重写拷贝构造,一经重写,系统不再提供。构造、析构、拷贝构造、赋值运算符重载发classclass{cout<<this<<"}A(constA{cout<<this<<"cpcontructorfrom}A&operator=(constA{cout<<this<<"operator=}{cout<<this<<"}a传值voidvoidfoo(Aint{Aa;return0;}b传,没有发生拷voidvoidfoo(A&int{Aa;return0;}c返回对AAfoo(A&{return}int{Aa;}在main的栈上事先开辟了一个临时空间,把这个空间的地址隐式的转到foo函数栈上。然后,把a内的东西,拷贝到临时空间中。所以发生一次构造,一次拷贝,两次析构AAfoo(A&{cout<<"infoo:"<<(void*)&a<<endl;returna;}int{AAtt=cout<<"inmain:"<<(void*)&t<<endl;return0;}此时main函数中产生的临时空间,由t来取而代之。所以也发生一次构造,一次拷贝,两次析构。此时的地址,同a的地址不同AAfoo(A&{Acout<<"infoo:"<<(void*)&b<<endl;returnb;}int{AAtt=cout<<"inmain:"<<(void*)&t<<endl;return0;}此时发生了两次构造,两次析构。也就是main中的t取代了临时空间,而b的构造完成了t的构造。所在完成了两次构造,两次析构。而不是三次。浅拷贝和深拷贝##include<iostream>#include<string.h>usingnamespacestd;classA{A(char*voiddis(){}intlen;stringname;int{A return0;}当类成员中含有一个const对象时,或者是一个时,他们也必须要过成员初始化列表进行初始化,因为这两种对象要在后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。static数据类型成员变量;//在类的//初始数据类型类名::静态数据成员=初值;//在类的//调1,static成员变量实现了同类对象间信息共2,static成员类外,求类大小,并不包含在内3,static成员是命名空间属于类的全局变量,在data区4,static成员只能类外初始化成员变量普通成员变量:于对象中,与strc变量有相同的内存布局和字节对齐方式函数类型operator运算符名称(形参表列{重载实体} 例如,有人觉得BASIC中用“**”作为幂运算符很方便,也想在C++中将“**”定义为幂运算符,用“3**5”表示3的5次幂,这是不行的。C++中绝大部分运算符都不能重载的运算符.成员选择运算.*成员对象选择::作用域运算?:sizeofsizeof运算符的运算对象是类型而不是变量或一般表达式,不具备重载的特如,关系运算符“>”和“<”等是双目运算符,重载后仍为双目运算符需要两个参数。运算符”“,”*“,”“等既可以作为单目运算符,也可以作为双目运算符,可以分别将它们重载为单目运算符或双目运算符。重载不能改变运算符的优先级别例如”*“和”/“优先级高于”+“和”“,不论怎样进行重载,各运算符之间的优先级不会改变。有时在程序中希望改变某运算符的优先级,也只能使用加括号的方法强制改变重载运算符的运算顺序。如,运算符”=“是右结合性(自右至左),重载后仍为右结合性否则就改变了运算符参数的个数,与前面第(3)点重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象) 成员的运算符的性质,如下面这样是不对的代码代码如下intoperator+(inta,int{return(ab);相减。如果允许这样重载的话,如果有表达式4+3,它的结果是7还是1呢?显然,这是绝对要的。用于类对象的运算符一般必须重载,但有两个例外,运算符”=“和运算符”&“不必用户重载。运算符”=“可以用于每一个类对象,可以用它在因为系统已为每一个新的类重载了一个赋值运算符,它的作用是逐个类中的数据成员地址运算符&也不必重载,它能返回类对象在内存中的起始地址。应当使重载运算符的功能类似于该运算符作用于标准类型数据时候时所实现的功能例如,我们会去重载”+“以实现对象的相加,而不会去重载”+“以实现对象相减的功能,因为这样不符合我们对”+“原来的认知。运算符重载函数可以是类的成员函数,也可以是类的函数,还可以是既非类的成员函数也不是数的普通函 operator#(L,R);//全局函数L.operator#(R);//成员函 #M或者M# //全局函 //成员函istream&operator>>(istream&operator>>(istream&,自定义类&);ostream&operator<<(ostream&,自定义类在C++中可重用性(softwarereusability)是通过继承(inheritance)这一机制来实现的。如果没有掌握继承性,就没有掌握类与对象的精华。has-A,uses-A和is-hs-A包含关系,用以描述一个类由多个“部件类”构成。实现hs-A关系用类成员表示,即一个类中的数据成员是另一种已经定义的类。uses-A一个类部分地使用另一个类。通过类之间成员函数的相互联系,定义友员或对象参数传递实is-A机制称为“继承”。关系具有传递性,不具有对称性语法classclass派生类名:[继承方式]基类名派生类成 }继承公有继承不可保护继承不可私有继承不可public公有继承类中不变,而基类的私有成员不可。即基类的公有成员和保护成员被继承到派生类中仍作为派生类的公有成员和保护成员。派生类的其他成员可以直接它们。无论派生类的成员还是派生类的对象都无法基类的私有成员。protected保护继承:员身份出现在派生类中,而基类的私有成员在派生类中不可。基类的公有成员和保护成员被继承后作为派生类的私有成员,派生类的其他成员可以直接它们,但是在类外部通过派生类的对象无法。无论是派生类的成员还是通过派生类的对象,都无法从基类继承的私有成员。通过多次私有继承后,对于基类的成员都会成为不可。因此私有继承比较少用。private私有类中,而基类的私有成员不可。派生类的其他成员可以直接从基类继承来的公有和保护成员,但是类外部通过派生类的对象无法它们,无论派生类的成员还是派生类的对象,都无法基类的私有成员。如何恰当的使用publicprotectedprivate#include<iostream>usingnamespacestd;classObject{Object(constchar*{cout<<"Object()"<<""<<s<<}{cout<<"~Object()"<<}classParent:public{Parent(constchar*s):{cout<<"Parent()"<<""<<s<<}{cout<<"~Parent()"<<}classChild:public{Child():o2("o2"),o1("o1"),Parent("Parameterfrom{cout<<"Child()"<<}{cout<<"~Child()"<<}Objectvoid{Child}intmain(intargc,char{}多继构造函数语法派派生类名::派生类名(参数总表):基类名1(参数表1),基类名(参数名基类名n(参数名n),内嵌子对象1(参数表内嵌子对象2(参数表2)....内嵌子对象n(参数表{派生类新增成员的初始化语句}虚继如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论