我的C++学习笔记.docx

上传人:b****7 文档编号:8913935 上传时间:2023-02-02 格式:DOCX 页数:13 大小:21.52KB
下载 相关 举报
我的C++学习笔记.docx_第1页
第1页 / 共13页
我的C++学习笔记.docx_第2页
第2页 / 共13页
我的C++学习笔记.docx_第3页
第3页 / 共13页
我的C++学习笔记.docx_第4页
第4页 / 共13页
我的C++学习笔记.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

我的C++学习笔记.docx

《我的C++学习笔记.docx》由会员分享,可在线阅读,更多相关《我的C++学习笔记.docx(13页珍藏版)》请在冰豆网上搜索。

我的C++学习笔记.docx

我的C++学习笔记

1.结构体struct和类class可以互换,本质结构体是一种特殊的类,struct默认是public而class默认是private

2.Consinta;常量是要进行初始的。

a

(1);

3.引用必须在定义的时候初始化。

4.全局变量或者全局对象,在进入main函数之前就已经分配好了内存空间

5.当基类的构造函数是为缺省的值时,在派生子类实例化时基类构造可以不带参数。

6.:

:

Showwindow()这样的前面加两个冒号,表示调用的是全局函数,即平台sdk的函数。

7.用const结尾的成员函数只能调用其他const结尾的成员函数。

因为其他函数并不能保证同样不修改类的成员变量

 成员函数后加const,表示:

类作者提示你,这个函数不会导致对象状态改变 

 可以理解为"表示这个函数不会修改任何成员变量" 

 但不可绝对化。

其实,还是可以修改由mutable关键字修饰的成员变量的。

8.C++中,构造函数和析构函数可以被显示调用.显示调用默认构造函数的语法:

a.A:

:

A();(不能写成a.A();),显示调用非默认构造函数的语法:

a.A:

:

A(7);(不能写成a.A(7););显示调用析构函数的语法:

a.A:

:

~A();(可以写成a.~A();). 

显示调用构造函数和析构函数就像调用一般的函数一样,并不意味着创建或销毁对象; 

如果构造函数中动态分配了空间,则显示调用构造函数会造成内存泄露.创建对象时的隐式构造函数调用已经为对象分配了动态内存.当用创建好的对象显示调用构造函数时,对象指向的动态内存更新显示调用时所分配的,对象生命周期结束时析构函数所释放掉的是后一次分配的动态内存,也就是说创建对象时隐式构造函数调用所分配的那块内存泄漏了. 

如果析构函数中释放动态分配的空间,则会造成多次释放同一内存,会出现严重错误.

9.析构函数和内存释放,有一篇的总结,因为内容长,以后贴上来

先看个简易的

classA

{

public:

   A(inti=3){a=i;};

   ~A(){cout<<"destructor"<

   intvalue(){returna;}

private:

   inta;

};

intmain()

{

   Aa;

   A*p=new(&a)A(10);

   cout<

   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

  #include

  //行参数指向const类型变量的指针

  voiddisplay_c(consint*pi)

  {

    cout<<"display_c:

"<<*pi<

  }

  //行参为普通类型变量的指针

  voiddisplay(int*pi)

  {

    cout<<"display_c:

"<<*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

{

   intmodel;

   namespacesize

   {

     intlenth;

     intwidth;

   }

}

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]

}

voidmain()

{

void*pv=null;

unsignedcharc1=0x12;

pv=&c1;

ShowHex(pv,sizeof(c1));

}

9typeid运算符用来求得变量或队形爱女嘎的数据类型,返回一个type_info类型的对象,通过该对象

可以获取数据类型的名称

21.include

inti;

consttype_info&t0=typeid(i);

t0.name();

10函数

  1模板函数

templateTmin(R&x,Tv&y)

{

  returnx

x:

y;

}

2指向函数的指针

  intmax(intx,inty)

{

   ...

}

intmin(intx,inty)

{

    ...

}

int(*m_pfunction)(int,int);

voidmain()

{

   m_pfunction=max;

   (*m_pfunction)(2,3);

    m_pfunction=min;

   (*m_pfunction)(2,3);

}

11类与对象

1构在函数和析构函数

#include

#include

#include

classBook

{

private:

 

char*pBookName;

public:

intPageNum;

public:

Book(char*pBN=NULL);

~Book(void);

voidSetBookName(char*pBN);

intGetBookName(char*pBN,unsignedintMaxSize);

};

22.Book:

Book(char*PBN)

{

cout<<"构造函数"<

pBookName=null;

if(oBN!

=null)

{

    pBookName=newchar[strlen(pBN)+1];

    if(pBookName!

=null)

        strcyp(pBookName,pBN);

}

}

23.Book:

:

~Book()

{

delete[]pBookName;

}

24.voidBook:

:

SetBookName(char*pBN)

{

if(pBookName!

=null)

   delete[]pBookName;

  pBookName=newchar[strlen(pBN)+1];

    if(pBookName!

=null)

        strcyp(pBookName,pBN);

}

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)

{

  month=m;

}

voidmain()

{

  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;

  public:

   int&CenterX;

   constintCenterY;

   CRect(intx1,inty1,intx2,inty2,int&x3,inty3)

    :

up_left(x1,y1),low_right(x2,y2),CenterX(x3),CenterY(y3)

  {

     

  }

};

voidmain()

{

intcx=5;

intcy=6;

CRectr1(1,2,3,4,cx,cy);

}

6拷贝构造函数

拷贝构造函数与普通构造函数的差别在与棋参数类表,参数列表中有一个对象,该对象的数据类型是

本类的一个引用,而且一般情况下,该对象还应该是一个const类型的对象。

如果在类的定义是不是显示的定义一个拷贝函数,则编译器会自动的定义一个拷贝构造函数

classCPoint

{

  public:

    intx,y;

    CPoint(intm_x=0,ubtm_y=0);  //defaultconstructor 

    cPoint(constCPoint&c);     //copyconsrucotr

};

CPoint:

:

CPoint(intm_x,intm_y)

{

   

}

CPoint:

:

CPoint(constCPoint&c)

{

  x=c.y;

  y=c.x;

}

29.voidmain()

{

  CPointc1(1,2);//invokedefaultconstructor

  CPointc2-c1;   //invokecopyconstructor

}

7templateclass

templateclassArray//templateclass

{

  private:

    Tarr[Size];

    intCurSize;

  public:

   Array(T*date,intn)

   {

     CurSize=n

n;Size;

     for(inti=0;i

     {

       Arr[i]=data[i]; 

     }

   }

}

30.voidmain()

{

inti1[10]={1,2,3,4,5,6,7,8,9};

Arrayarray_i1(i1,i0);

}

1友员类和友员函数

#include

#include

#include

31.classSoftWareEngineer;//先对SoftwareEngineer类进行显示说明一下

32.classComputer//定义Computer类

{

  private:

    intPrice;

  public:

    Computer(intp){Price=p};

   friendclassSoftwareEngineer;//将友员类载这里声明

   frinedvoidJudge(Computer&c,SoftwareEngineer&s)//友员函数

    

};

33.classSoftwareEngineer

{

  intSalary;

  charName[20];

public:

   SoftwareEngineer(ints,char*n//构造函数)

{

    Salary=s;

    strcpy(Name,n);

}

intGetComputerPrice(Computer&c){returnc.Price}//访问Computer的思友变量

friendvoidJudge(Computer&c,SoftwareEngineer&s)//友员函数

};

//判断一个软件工程师是否可以用一个月的薪水买的器一台电脑

voidJudge(Computer&c,SoftwareEngineer&s)//桥友员函数

{

  if(c.Price>s.Salary)

    cout<<"软件工程师"<

  else

    cout<<"软件工程师"<

voidmain()

{

Computerc1(100);

SoftwareEngineers1(120,"user1");

Judge(c1,s1);

34.SiftwareEngineers2(80,"user2")

Judge(c1,s2);

getch();

}

2运算符重载 

#include

#include

#include

35.classTValue{

private:

    intvalue;

public:

  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&operator<<(ostream&os,TValuerv)

{

  os<

returnos;

}

39.voidmain()

{

  TValuev1(3),v2(5);

  cout<<

}

3类的派生和继承

1classBox{

  public:

    intwidth,height;

    voidSetWidth(intw){width=w};

    voidSetWidth(inth){height=h;};

};

classTColorBox:

:

publicBox{

public:

    intcolor;

    voidSetColor(intc){color=c;};

};

40.voidmain(){

   TColorBoxcb;

   cb.SetColor(255);//声明非继承类的对象

   cb.SetWidth(100);//声明继承类的对象

   cb.SetHeight(100);//声明继承类的对象

   

}

2不能被继承的成员

构造函数,析构函数,用户定义的新操作符,用户定义的赋值操作,友员关系

3构造函数,析构函数的调用顺序

classA{

inta,b,c;

public:

A(intx,inty,intz)

{

  a=x;

  b=y;

c=z;

}

41.};

classB{

intd;

public:

  B

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 生物学

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

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