我的C++学习笔记Word文档格式.docx
- 文档编号:22050087
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:13
- 大小:21.52KB
我的C++学习笔记Word文档格式.docx
《我的C++学习笔记Word文档格式.docx》由会员分享,可在线阅读,更多相关《我的C++学习笔记Word文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
~A(){cout<
<
"
destructor"
<
endl;
}
intvalue(){returna;
private:
inta;
intmain()
Aa;
A*p=new(&
a)A(10);
cout<
a.value()<
deletep;
return0;
在a对象的地址上未析构a的时候,创建了新的无名堆对象,这样a的数据被覆盖了,
但是编译器并未收到析构函数调用的消息,所以它认为那块内存存放的仍然是a对象的数据,所以a.value()仍可以取回值,取回当时内存中那个地址处的值,这是已经是10了。
然后deletep的时候,执行两步工作,
1。
无名对象的析构函数调用,告诉编译器,那块内存中的值不能解释成无名对象的数据了,对于无名对象而言,已经无效了(但对于a对象而言,因为编译器并未收到a对象析构函数的调用,所以认为那块内存中的数据对于a而言仍是有效的,是a的数据的)
2。
问题发生在这个时候,deletep的第二个动作,归还内存给系统,标识为空闲内存(没有任何对象引用到的,没有任何函数占用的内存),而事实上,这是对于p所指对象而言,对于a对象,它仍引用到这块内存,这样产生了异常,系统认为是快空闲内存了,但确有个对象引用到了这块内存,行为属未定义。
这就好像两个指针指向同一块的内存,一个把内存释放了,另一个指针成了悬垂指针,对悬垂指针解引用取出的值无意义,随机的,看当时内存中的数据
简单的说,
构造函数就是通知编译器,这块内存的数据解释成一个对象,哪块是哪个数据成员的数据,这些信息是构造函数给编译器的,都是隐式给的;
显式的动作可以放在构造函数中(并未必需的)的,是初始化(不给初始化值可以的,随机值),获取资源
析构函数就是通知编译器,这块内存中的数据以后无需维护了,可以让其它使用了,里面的数据再不能解释成类对象的数据了,析构函数调用之后可以两种选择
1。
一般情况,归还内存,栈的,堆的,都是
2。
保留内存,只析构对象,这常见于placementnew,delete往往同时执行了两个动作,所以这是候并不能直接delete,而是显式调用析构函数(详细论述待以后的总结)
10.学习笔记之c++
11.int*pia=newint[10];
我们并不能给动态分配的数组每个元素一个初始化值,语法并不支持
基于这个原因,对于对象数组
如果并没有默认构造函数,不能创建动态对象数组,因为new对象数组的时候,自动调用构造函数以建立对象,(new不只是分配内存而已,而且给编译器标识出这块内存存放的是什么类型的对象,int,classA,这也属于new的行为,所以它调用构造函数,以提供识别数据类型,解析二进制数据流的能力)如果并没有默认构造函数,
语法上不支持逐个初始化列表给动态数组,这样就没法构造对象了
容器vector和内置数组类型,是一个道理,
关键在于理解:
new的动作不只是分配内存,而且进行类型标识的行为
12.两者释放的资源是不一样的,delete释放p指向的内容,它也调用析构函数,也就是说,后者包含前者
而析构函数不释放p指向的内容,而是p指向的对象的成员变量占用的资源(不一定是内存,还可能是其他资源,如文件句柄/窗口/socket等)
13.类的静态成员与常成员
14.Const
15.1const与volatile的用法
1const
#include<
conio.h>
iostream.h>
//行参数指向const类型变量的指针
voiddisplay_c(consint*pi)
{
cout<
"
display_c:
*pi<
endl;
}
//行参为普通类型变量的指针
voiddisplay(int*pi)
//const类型变量
constinti1=1;
//errori1=3;
//const类型变量的指针
inti2=2;
constint*pi2=&
i2;
//error*pi2=3
//const指针
int*constpi3=&
i3;
*pi3=5;
//error*pi3=&
i4可以赋予不同的值,但是不可一指向不同的变量
//指向const内容的const指针
constint*cosntpi5=&
i5;
2sizeof返回某个便赖宁嘎或数据类型的长度
3引用
1引用变量
inti=1;
int&
r_i=i;
5名空间
1namespace
namespacecar
intmodel;
intlength;
intwidth;
namespaceplane
namespacesize
intlenth;
namespacecar//添加名空间的成员
char*name;
namespqcec=car;
//定义别名
intTime//外不变量属于全局名空间
car:
length=3;
plane:
size:
length=70;
intTime=1996;
Time=1997;
16.2using
voidmain()
usingnamespacecar;
length;
usingnamespacephane;
model;
17.}
6new与delete运算符
double*pd;
//definepointervariable
pd=newdouble;
//allocatememory
if(pd!
=null)
...
deletepd;
//freememory
18.double1=null
*pds=newdouble[100];
if(pds)
....
delete[]pds;
19.}
20.如果是使用new进行内存空间分配没有成功,则返回空指针null
释放一个数组分配的内存是,常常采用带[]的形式
7void指针它指向一个地址值,但是不说名数据类型,可以使用void指针创建一个通用的函数,在使用
的时候将指针类型转化成相应的具体类型。
voidShowHex(void*pv,intsiae)
....
((unsignedchar*)pv)[i]
void*pv=null;
unsignedcharc1=0x12;
pv=&
c1;
ShowHex(pv,sizeof(c1));
9typeid运算符用来求得变量或队形爱女嘎的数据类型,返回一个type_info类型的对象,通过该对象
可以获取数据类型的名称
21.include<
typeinfo.h>
inti;
consttype_info&
t0=typeid(i);
t0.name();
10函数
1模板函数
template<
classT>
Tmin(R&
x,Tv&
y)
returnx<
y?
x:
y;
2指向函数的指针
intmax(intx,inty)
intmin(intx,inty)
int(*m_pfunction)(int,int);
m_pfunction=max;
(*m_pfunction)(2,3);
m_pfunction=min;
11类与对象
1构在函数和析构函数
#include<
string.h>
classBook
char*pBookName;
intPageNum;
Book(char*pBN=NULL);
~Book(void);
voidSetBookName(char*pBN);
intGetBookName(char*pBN,unsignedintMaxSize);
};
22.Book:
Book(char*PBN)
cout<
构造函数"
pBookName=null;
if(oBN!
pBookName=newchar[strlen(pBN)+1];
if(pBookName!
strcyp(pBookName,pBN);
23.Book:
~Book()
delete[]pBookName;
24.voidBook:
SetBookName(char*pBN)
if(pBookName!
=null)
delete[]pBookName;
25.intBook:
GetBookName(char*pBN,unsignedintmaxSize)
if((pBookName!
=null))&
&
(MaxSize>
strlen(pBookName))
strcpy(pBN,pBookName);
retrunstrlen(strlen(pBookName));
26.//使用
Bookb1;
b1.SetBookName("
test"
Bookb2(test1);
2对象的引用参数传递
voidAdd(Bookb)
voidAddRef(Book&
b);
3静态成员变量是一个公共变量
在初始化的时候利用作用运算符:
对私有类型的静态成员变量可以向公有类型的静态成变量一样赋值
但不能直接引用
3const类型成员函数与mutable
classCDate
public:
intyear;
mutableintmonth;
CDate(inty=2000,intm=1)
year=y;
month=m;
};
intBetMonth()const;
//readonly
voidSetMonth(intm);
//writeonly
voidCDate:
SetMonth(intm)
CDated1;
27.在const类型的成员函数定义中,不可一直接或简介的修改普通类型的成员变量
如果象修改const类型对象的成员函数,可以使用关键字mutable对该成员变量进行修改
5对象的初始化与初始化行
将参数类表中的数值赋予成员变量时,不仅可以在构造函数的函数体中进行,以阿宽衣在初始化行中进行
在初始化处惊醒初始化的情况有:
1分层类的构在函数可以调用它的任何一个子对象的构造函数
2对常量const类型的成员变量的初始化必须在初始化行上
3对于引用类型的成员变量的初始化必须在初始化行上
classCPoint
public:
intx,y;
CPoint(intax=0,intay=0)
x=ax;
y=ay;
28.classCRect
private:
CPointlow_right;
CPointup_left;
int&
CenterX;
constintCenterY;
CRect(intx1,inty1,intx2,inty2,int&
x3,inty3)
:
up_left(x1,y1),low_right(x2,y2),CenterX(x3),CenterY(y3)
intcx=5;
intcy=6;
CRectr1(1,2,3,4,cx,cy);
6拷贝构造函数
拷贝构造函数与普通构造函数的差别在与棋参数类表,参数列表中有一个对象,该对象的数据类型是
本类的一个引用,而且一般情况下,该对象还应该是一个const类型的对象。
如果在类的定义是不是显示的定义一个拷贝函数,则编译器会自动的定义一个拷贝构造函数
CPoint(intm_x=0,ubtm_y=0);
//defaultconstructor
cPoint(constCPoint&
c);
//copyconsrucotr
CPoint:
CPoint(intm_x,intm_y)
CPoint(constCPoint&
c)
x=c.y;
y=c.x;
29.voidmain()
CPointc1(1,2);
//invokedefaultconstructor
CPointc2-c1;
//invokecopyconstructor
7templateclass
classt,intSize>
classArray//templateclass
Tarr[Size];
intCurSize;
Array(T*date,intn)
CurSize=n<
Size?
n;
Size;
for(inti=0;
i<
CurSize;
i++)
Arr[i]=data[i];
30.voidmain()
inti1[10]={1,2,3,4,5,6,7,8,9};
Array<
int,6>
array_i1(i1,i0);
1友员类和友员函数
#include<
31.classSoftWareEngineer;
//先对SoftwareEngineer类进行显示说明一下
32.classComputer//定义Computer类
intPrice;
Computer(intp){Price=p};
friendclassSoftwareEngineer;
//将友员类载这里声明
frinedvoidJudge(Computer&
c,SoftwareEngineer&
s)//友员函数
};
33.classSoftwareEngineer
intSalary;
charName[20];
SoftwareEngineer(ints,char*n//构造函数)
Salary=s;
strcpy(Name,n);
intGetComputerPrice(Computer&
c){returnc.Price}//访问Computer的思友变量
friendvoidJudge(Computer&
//判断一个软件工程师是否可以用一个月的薪水买的器一台电脑
voidJudge(Computer&
s)//桥友员函数
if(c.Price>
s.Salary)
软件工程师"
s.Name<
的一个月薪水买不起一台电脑"
else
的一月薪水买的起一台电脑"
}
Computerc1(100);
SoftwareEngineers1(120,"
user1"
Judge(c1,s1);
34.SiftwareEngineers2(80,"
user2"
)
Judge(c1,s2);
getch();
2运算符重载
iomanip.h>
35.classTValue{
intvalue;
TValue(inti){value=i}
//成员函数重载运算符
TValueoperator!
();
TValueoperator+(TValue&
rv);
//友员函数重载运算符
friendostream&
operator<
{ostream&
os,TValue&
rv};
36.TValueTvalue:
operator!
()
returnTValue(!
value);
37.TValueTValue:
operator+(TValue&
rv)
returnTValue(value+rv.value);
38.ostream&
(ostream&
os,TValuerv)
os<
setw(5)<
rv.value;
returnos;
39.voidmain()
TValuev1(3),v2(5);
3类的派生和继承
1classBox{
intwidth,height;
voidSetWidth(intw){width=w};
voidSetWidth(inth){height=h;
classTColorBox:
publicBox{
intcolor;
voidSetColor(intc){color=c;
40.voidmain(){
TColorBoxcb;
cb.SetColor(255);
//声明非继承类的对象
cb.SetWidth(100);
//声明继承类的对象
cb.SetHeight(100);
//声明继承类的对象
2不能被继承的成员
构造函数,析构函数,用户定义的新操作符,用户定义的赋值操作,友员关系
3构造函数,析构函数的调用顺序
classA{
inta,b,c;
A(intx,inty,intz)
a=x;
b=y;
c=z;
41.};
classB{
intd;
public:
B
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 学习 笔记
![提示](https://static.bdocx.com/images/bang_tan.gif)