客观事物中任何一个事物都可以看成一个对象,对象是由一组属性和一组行为构成的。
c++中,每个对象都是由数据函数这两部分构成,数据就是对象的属性,函数就是对象的行为。
c++中对象的类型称为类,类是一批对象的共性和特征。类是对象的抽象,对象是类的具体实例。

如何声明一个类:

  1. class Time
  2. {
  3. public : //成员访问限定符
  4. 公有数据和成员函数
  5. private : //成员访问限定符
  6. 私有数据和成员函数
  7. protected:
  8. 受保护数据和成员函数
  9. };

如何定义对象:
1. 先声明类类型,然后定义对象

2. 在声明类的同时定义对象

  1. class Time
  2. {
  3. public :
  4. Time ();
  5. void set_time (); //成员函数说明
  6. void show_time ();
  7. private :
  8. int hour;
  9. int minute;
  10. int sec;
  11. } tim1,tim2;

类的成员函数:在类体中定义的函数,同一个类的不同对象,其成员函数是共用的
,每个对象所占用的存储空间只是该对象的数据成员所占用的存储空间。

如何访问对象的中的成员:
1.对象名.对象成员
2.通过对象指针访问对象成员
Time *p t1;
p=&t1;
p->hour;
3.通过对象应用访问对象成员
Time t1;
Time &t2=t1;
t2.hour;

怎样使用类和对象
利用构造函数对类进行初始化:
构造函数的名字必须与类名同名,它不具有任何类型,没有返回值。
在建立类对象时会自动调用构造函数。在建立对象时系统为该对象分配存储单元,此时执行构造函数,赋予初始值。

  1. class Time
  2. {
  3. public :
  4. Time ();
  5. void set_time (); //成员函数说明
  6. void show_time ();
  7. private :
  8. int hour;
  9. int minute;
  10. int sec;
  11. };
  12. Time::Time () //定义构造成员函数
  13. { //利用构造成员函数进行初始化
  14. hour =;
  15. minute =;
  16. sec =;
  17. }

这种方式使该类的每一个对象的数据成员都得到同一组初值。

如何对不同对象赋予不同初值?使用带参数的构造函数
构造函数名(类型1 形参1 )
类名 对象名(实参1 实参2 实参3...)

  1. class Box
  2. {
  3. public:
  4. Box(int ,int, int ); //对不同的对象赋予不同的初始值
  5. int volume ();
  6. private:
  7. int height;
  8. int width;
  9. int length;
  10. };
  11. Box::Box(int h,int w,int len)
  12. {
  13. height =h;
  14. width =w;
  15. length =len;
  16. }

参数初始化表对数据成员初始化(在函数首部初始化,而不是在函数体内对数据成员初始化)
Box::Box(int h,int w,int len):height(h),width(w),length(len){}
//用参数的初始化表法可以减少函数体长度
如果数据成员是数组,则应当在构造函数的函数体中用语句对其赋值,而不能在参数初始化表中对其初始化。
class student
{public:
student(int n,char s,nam[]):num(n),sex(s){strcpy(name,nam)}
private:
int num;
char sex;
char name[20];
};

构造函数的重载
在一个类中可以定义多个构造函数,以便为对象提供不同的初始化的方法,这些构造函数名字相同,二参数的个数或参数的类型不同,这称为构造函数的重载。
使用默认参数的构造函数

  1. class Box
  2. {
  3. public:
  4. Box(int h= ,int w=, int len= ); //也可以写成Box(int =10 ,int =10, int =10 );
  5. int volume ();
  6. private:
  7. int height;
  8. int width;
  9. int length;
  10. };
  11.  
  12. Box::Box(int h,int w,int len)
  13. {
  14. height =h;
  15. width =w;
  16. length =len;
  17. }

  

注意:
1 如果构造函数的全部参数都指定了默认值,则在定义对象时可以给一个或几个实参。
2 在一个类中定义了全部是默认参数的构造函数后,不能再定义重载构造函数。

析构函数,其作用与构造函数相反
在下列4中情况中,程序会自动执行析构函数。
1 如果在一个函数中定义了一个对象,当这个函数被调用结束时,对象应该释放,在对象释放前自动执行析构函数。
2 静态(static)局部对象在函数调用结束时对象并不释放,因此也不调用析构函数,只有在main 函数结束或者调用exit函数结束程序时,才调用static局部对象的析构函数。
3 定义了一个全局对象,
4 用new运算符动态建立了一个对象,用delete运算符释放该对象时调用析构函数。
析构函数用例:

  1. #include<iostream>
  2. using namespace std;
  3. class Box
  4. {
  5. public:
  6. Box(int ,int, int ); //对不同的对象赋予不同的初始值
  7. int volume ();
  8. ~Box()
  9. {cout<<"construct called"<<volume()<<endl;}
  10.  
  11. private:
  12. int height;
  13. int width;
  14. int length;
  15. };
  16.  
  17. Box::Box(int h,int w,int len)
  18. {
  19. height =h;
  20. width =w;
  21. length =len;
  22. }
  23. int Box::volume()
  24. {
  25. return (height*width*length);
  26. }
  27.  
  28. int main()
  29. {
  30. Box box1(,,);
  31. cout<<"The volume of box1"<<box1.volume()<<endl;
  32. Box box2(,,);
  33. cout<<"The volume of box1"<<box2.volume()<<endl;
  34. return ;
  35.  
  36. }

  

上面程序运行结果显示,先构造的后析构,后构造的先析构。相当与一个栈。
但是,并不是在任何情况都按这一原则处理的。
1 在全局范围中定义对象,它的构造函数在文本模块中所有函数执行前调用。
2 如果定义的是局部自动变量,则在建立对象时调用其构造函数,在函数调用结束时、对象释放时先调用析构函数。
3 在函数中定义静态局部对象,只在第一次调用此函数定义对象时调用构造函数一次,在main函数结束或调用exit 函数结束程序时,才调用析构函数。

对象数组(数组中每一个元素都是同类的对象)
例如:

  1. class student
  2. {...
  3. };
  4. student stud[]={
  5. student(,,,),
  6. student(,,,)
  7. student(,,,)
  8. };

  

对象指针
student *st; 
student stud1;
st=&stud1;

指向对象成员的指针
对象有地址,存放对象的起始地址的指针变量就是指向对象的指针变量。
对象中的成员也有地址,存放对象成员地址的指针变量就是指向对象成员的指针变量。
1.指向对象数据成员的指针
数据类型名 *指针变量名
2.指向对象成员函数的指针
数据类型名(类名::*指针变量名)(参数表名)
void(Time::*p)();
指针变量名=&类名::成员函数名;

常对象成员
1.常数据成员(其值是不能改变的,只能通过构造函数的参数初始化表对常数据成员进行初始化,任何其他函数都不能对常成员赋值)
Time::Time(int h)
{hour=h;} //非法,不能对其赋值
Time::Time(int h):hour(h){}

2.常成员函数
一般的成员函数可以引用本类中的非const数据成员,也可以修改他们。如果将数据成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改他们。
void get_time() const; 
类型名 函数名 (参数表) const;
const 是函数类型的一部分,在声明函数和定义函数的时都要有const关键字,在调用时不必加const

指向对象的常指针(指针常量)
类名*const 指针变量名; //指向对象的常指针的值不能改变,始终指向同一个对象,但可以改变其所指向的对象的值。
往往用常指针作为函数的形参,目的是不允许在函数执行过程中改变指针变量的值,使其始终指向原来的对象。

指向常对象的指针变量(常量指针)
const 类型名*指针变量 
const char* ptr; //指针变量ptr指向的char 变量是常变量,不能通过ptr改变其值。
说明:
1 .如果一个变量以被声明为常变量,只能用指向常变量的指针变量指向它
2 .如果函数的形参是指向普通变量的指针变量,实参只能用指向普通变量的指针,而不能用指向const 变量的指针,这样在执行函数的过程中可以改变改变形参所指向的变量。
当希望在调用函数时对象的值不被修改,就应当把形参定义为指向常对象的指针变量,同时用对象的地址作为实参(对象可以是const或者非const型)

对象的常引用
一个变量的引用就是变量的别名。实质上,变量名和引用名都指向同一段内存地单元。

对象的动态建立和释放
有时人们希望在需要用到对象时在建立对象,在不需要用该对象时就撤销它,释放它所占用的内存空间,这样可以提高内存空间的利用率
用new运算符动态分配内存后,将返回一个指向新对象的指针,即所分配的内存空间的起始地址。
用户可以获得这个地址,并通过这个地址来访问这个对象。
Box *pt;
pt=new Box;

在执行new运算时,如果内存量不足,无法开辟所需的内存空间,编译系统会放回一个NULL。

在不需要使用由new建立的对象时,可以用delete运算符予以释放。
delete pt;

对象的赋值与复制
对象1=对象2;
对象的赋值只对其中数据成员赋值,而不对成员函数赋值。
类的数据成员中不能包括动态分配的数据,否则在赋值时可能出现严重后果。

对象的复制
类名 对象2(对象1); //用对象1复制出对象2
括号中的参数是对象,在建立对象时调用一个特殊的构造函数--复制构造函数
类名 对象2=对象1; //另一种方便用户的复制形式

对象的赋值时对一个已经存在的对象赋值,因此必须先定义被赋值的对象,才能进行赋值。
对象的赋值是从无中到有的建立一个新对象,并使它与一个已有的对象完全相同的过程。

静态成员(在同类的多个对象之间实现数据共享)
1.静态数据成员
是一种特殊的数据成员,以关键字static开头
如果希望各对象中数据成员的值是一样的,就可以把它定义为静态数据成员
1. 静态数据成员在内存中只占一份内存空间,每个对象都可以引用这个静态数据成员
2. 静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放。(静态数据成员并不是属于对象的,而是属于类的,但类的对象可以引用)
静态数据成员在程序开始运行时被分配空间,到程序结束时才释放空间。
3. 静态数据成员可以初始化,但是只能在类体外进行。不能用参数初始化列表对静态成员初始化
4. 静态数据成员尽既可以通过对象名引用,又可以通过类名来引用。

2.静态成员函数 (是类的一部分,而不是对象的一部分)
static int volume();
静态成员函数作用不是为了对象之间的沟通,而是为了能够处理静态数据成员。
静态成员函数不属于某一对象,与任何对象都无关,因此静态成员函数没有this指针,
也无法指定某个对象,也就无法访问本类中的非静态成员。
只用静态成员函数引用静态成员,而不引用非静态数据成员。

友元
1.友元函数
如果在本类以外的其他地方定义了一个函数(这个函数可以属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明此函数就称为本类的友元函数。
友元函数可以访问这个类中中的私有成员。

2.友元类
将一个类声明为另一个类的朋友,
class A
{...
friend B; //在类A中声明B为其友元
...
};

关于友元类的说明:
1. 友元的关系是单向的,上面的例子中B类是A类的友元,不等于A类是B类的友元
2. 友元的关系不能传递

类模板
函数模板(对于功能相同而数据类型不同的一些函数,不必一一定义各函数,可以定义一个可对于任何类型变量进行操作的函数模板,
在调用函数时,系统会根据实参类型,取代函数模板中的类型参数,得到具体函数)
template<class 类型参数名> //声明模板类

template<class
numtype>

class compare

{

public:

compare(numtype
a,numtype b);

{x=a;y=b;}

numtype max()

{return
(x>y)?x:y;}

numtype min()

{return
(x<y)?x:y;}

private:

numtype x,y;

};

  

compare<int>cmp(4,6);
//变成一个实际的类

template <class
numtype> //在类模板外定义方式
numtype compare<numtype>::max()
{return (x>y)?x:y;}

可以这样声明和使用类模板
1. 先写出一个实际的类
2.将此类准备改变的类型名(如int要改变成float或char)改用一个自己指定的虚拟类型名
3.在类声明前加入一行,格式为
template<class 虚拟类型参数>
4. 在类模板定义对象时用以下形式
类模板名<实际类型名>对象名;
类模板名<实际类型名>对象名(实参表);

compare<int>cmp;
compare<int>cmp(5,3);
5.如果在类模板外定义成员函数,应写出如下形式
template<class 虚拟类型参数>
函数类型 类模板名<虚拟类型参数>::成员函数名(函数参数表){...}

参考书目:c++程序设计》谭浩强

2019-09-04 
    19:37:17

C++语法笔记(上)的更多相关文章

  1. SQL基础语法笔记教程整理

    PS:本文适用SQL Server2008语法. 一.关系型数据库和SQL 实际上准确的讲,SQL是一门语言,而不是一个数据库. 什么是SQL呢?简而言之,SQL就是维护和使用关系型数据库中的的数据的 ...

  2. pyqt样式表语法笔记(上) --原创

    pyqt样式表语法笔记(上) pyqt QSS python 样式表 因为软件课设的原因开始学习使用pyqt4,才发现原来它也有样式表,而且语法跟css基本相同,而且一些功能实现起来感觉比js要简单方 ...

  3. SQL 基础语法笔记教程整理

    最近从图书馆借了本介绍 SQL 的书,打算复习一下基本语法,记录一下笔记,整理一下思路,以备日后复习之用. PS:本文适用 SQL Server2008 语法. 首先,附一个发现的 MySQL 读书笔 ...

  4. Typora笔记上传到博客

    Typora笔记上传到博客 Markdown是一种轻量级标记语言,排版语法简洁,让人们更多地关注内容本身而非排版.它使用易读易写的纯文本格式编写文档,可与HTML混编,可导出 HTML.PDF 以及本 ...

  5. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  6. [python] Pythonic语法笔记

    Pythonic语法笔记 __new__ 在类实例化之前执行的,也就是在init之前执行,可以为这个类写操作.接受的参数不是self而是cls.只有在new方法里返回类才会执行init操作,需要返回父 ...

  7. SQL Server 常用高级语法笔记

    自从用了EF后很少写sql和存储过程了,今天需要写个比较复杂的报告,翻出了之前的笔记做参考,感觉这个笔记还是很有用的,因此发出来和园友分享. 1.case...end (具体的值)case后面有值,相 ...

  8. 黑马程序员----java基础笔记上(毕向东)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 笔记一共记录了毕向东的java基础的25天课程,分上.中.下 本片为上篇,涵盖前10天课程 1. ...

  9. javaScript基础语法(上)

    相关理论概念: 直接量的概念:直接描述某个(些)存储空间的值的量,如变量的值.对象的值.数组的值. 数据类型:在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作. 1.变量的声明和使用 变 ...

随机推荐

  1. 【洛谷】P3177 [HAOI2015]树上染色

    懒得复制题面了直接传送门吧 分析 直接求点与点之间的距离感觉不是很好求,所以我们考虑换一个求法. 瞄了一眼题解 距离跟路径上边的长度有关,所以我们直接来看每一条边的贡献吧(这谁想得到啊) 对于每一条边 ...

  2. select下拉框多选取值

    本来是单选取值,现改为多选 其中<select> 标签新增multiple属性,如<select id = "sel"  multiple = "mul ...

  3. 数据结构Java版之堆&堆排序(九)

    堆分为大顶堆,和小顶堆. 什么是堆? 堆可以看成是一棵二叉树,二叉树的元素是一个数组不断的从左到右轮训放置.如果是大顶堆,则大的数放上面一层,小的数放下面一层.上一层的数,一定大于下一层的数.小顶堆则 ...

  4. SignalR要求_转自:https://www.cnblogs.com/humble/p/3855137.html

    SignalR 服务端组件可以被部署在诸多的服务器配置中,本节描述了它所支持的操作系统版本,.NET framework,IIS.以及其他组件 二.支持的服务器操作系统 SignalR服务端组件可以被 ...

  5. const经典面试题

    1> const int age1 = 21; age1 = 100; // 编译报错 2> int const age2 = 22; 3> const int *age3 = 23 ...

  6. Linux 的crond 任务调度

    一.原理示意图 二.概述 任务调度:是指系统在某个时间执行的特定的命令或程序 任务调度分类: 1.系统工作:有些重要的工作周而复始的执行.如病毒扫描等 2.个别用户工作:个别用户可能希望执行程序,比如 ...

  7. 深入浅出一致性Hash原理

    转自:https://www.jianshu.com/p/e968c081f563 一.前言 在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务 ...

  8. [Linux] 启用win10下Linux子系统

    转载请注明出处:https://www.cnblogs.com/lialong1st/p/12004080.html 最新的win10引入了Linux子系统,这样就免去了安装虚拟机或者双系统的麻烦. ...

  9. python中字符截取[-1]、[:-1]、[::-1]、[n::-1]等使用方法的详细讲解(建议留存)

    python涉及字符截取的详细功能讲解: str = ' print("str[0:3]:"+str[0:3]) # 正向截取字符串 0~3(不包含3) 即 012 print(& ...

  10. fdconnection自动重连

    fdconnection自动重连 1)设置 FDConnection1.ResourceOptions.AutoReconnect := True; 控制自动连接的恢复. 使用AutoReconnec ...