c++类与对象

注:部分来源于网络相关资料,用于个人总结学习记录,如有侵权,请联删。

1、面向对象的重要概念

(1)抽象:对具体对象进行概括,抽象出这一类对象的公共性质并加以描述的过程。

数据抽象

行为抽象

(2)封装:将抽象出的数据成员、行为成员相结合,将他们视为一个整体--类

使用者不需要了解具体的实现细节,只需要通过接口使用类的成员即可

(3)继承和派生:保持原有类特性的基础上,进行更具体的说明

2、定义类

类是用户自定义数据类型。如果程序中要使用类类型,必须根据实际需要定义,或者使用已设计好的类。

c++定义一个类,其方法与定义一个结构体类型是类似的,一般形式为:

其中成员列表是类成员的集合,数目可以任意多。大括号{ }是成员列表边界符,与成员列表一起称为类体、类体后面必须用分号结束

(1)每个类可以没有成员,也可以有多个成员

(2)类成员可以是数据或者函数

(3)所有成员必须在类的内部声明,一旦类定义完成后,就没有任何其他方式再添加成员了

类定义时必须给出各个数据成员的数据类型声明,一般形式为:

声明时成员名列表允许为多个,用逗号作为间隔,最后必须用分号结束。

如果类中有成员函数,则声明成员函数是必须的,而定义成员函数则是可选的,因此类的成员函数有两种形式:

(1)在类中定义成员函数,形式为:

(2)成员函数的声明在类内,定义在类外部,形式为:

类定义一般放在程序文件开头,或者放到头文件中被程序文件包含,此时这个定义是全局的。在全局作用域内,该定义处处可见,因此同作用域内的所有函数都可以使用它。

类定义也可以放到函数内部或局部作用域,此时这个定义是局部的。若在函数内部有同名的类定义,则全局声明在该函数内部是无效的,有效的是局部定义。示例如下:

c++规定,在局部作用域内声明的类,成员函数必须是函数定义形式,不能是原型声明。一般地,由于类是为整个程序服务的,因此很少有将类放到局部作用域中去定义

类定义向编译器声明了一种新的数据类型,该数据类型有不同类型的数据成员和成员函数。因此尽管数据成员类似变量的定义,但类型声明时并不会产生该成员的实体,即为它分配存储空间。数据类型都不占用存储空间

3、类成员的访问控制

对类的成员进行访问,来自于两个访问源:类成员和类用户

类成员指类本身的成员函数。类用户指类外部的使用者,包括全局函数、另一个类的成员函数等。

无论数据成员还是函数成员,类的每个成员都有访问控制属性,由以下三种访问标号说明:public、private、protected

公有成员:类成员和类用户都可以访问公有成员,任何一个来自类外部的成员都可以通过共有成员来访问。显然,public实现了类的外部接口

私有成员:只有类可以访问私有成员,类用户的访问是不允许的,private实现了私有成员的隐蔽

保护成员:在不考虑继承的情况下,protected的性质和private一致,但保护成员可以被被派生类的类成员访问。

成员访问控制更是c++的类和结构体又一个重要特征

如果没有声明访问控制属性,类所有成员默认为private,即私有的。

4、类的数据成员

类的数据成员可以是基本类型、数组、指针、引用、共用体、枚举类型、void指针、const限定等数据类型,例如:

类的数据成员还可以是成员对象,即类类型或者结构体类型的对象。若类A中嵌入了类B的对象,则称这个对象为子对象,例如:类Line嵌入了类Point的子对象start、end。

在类中定义或声明数据类型

除了定义数据成员和成员函数之外,类还可以定义自己的局部类型,并且使用类型别名来简化。

在类中定义或声明的数据类型的作用域是类内部,因此,它们不能在类外部使用。

类定义中,可以定义结构体和共用体类型,嵌套的类定义,声明枚举类型。

5、类的成员函数

(1)在类外部定义成员函数

如果成员函数仅有声明在类定义中,则在类外部必须有它的实现,其一般形式为:

举例:

说明:

1):: 是作用域限定符。如果在作用域限定符的前面没有类名,或者函数前面既无类名又无作用域限定符,例如:

::set(10)或set(10)

则表示set函数不属于任何类,这个函数不是成员函数,而是全局的普通函数。此时的::不是类作用域限定符的含义,而是命令空间域限定符的含义

2)类的内部声明成员函数,而在类外部定义成员函数,有助于类的接口和实现分离。

6、内联成员函数

类的成员函数可以指定为inline,即内联函数。

默认情况下,在类体中定义的成员函数若不包含循环等控制结构,符合内联函数要求时,c++会自动将它们作为内联函数处理(隐式内联)。

也可以显式地将成员函数声明为inline,例如:

判断成员函数是否是内联的,有以下几条:

(1)符合内联函数要求。比较简单并且没有循环控制语句

(2)符合1的条件,并且在类体中定义,自动成为内联的

(3)符合1的条件,在类体显式指明inline,或在外部定义时显式指明inline,或者同时显式指明,则函数是内联的

(4)在类外部定义,并且既没有在类体,也没有在外部定义时显式指明inline,则函数不是内联的。

7、成员函数重载及默认参数

可以对成员函数重载或使用默认参数,例如:

注意:声明成员函数地多个重载版本或指定成员函数地默认参数,只能在类内部进行。

因为类定义中地声明先于成员函数地外部实现,根据重载或默认参数函数的要求,必须在第一次出现函数声明或定义时就明确函数是否重载或有默认参数。

8、成员函数的存储方式

用类实例化一个对象时,系统会为每一个对象分配存储空间。如果一个类包括了数据成员和成员函数,则要分别为函数和函数的代码分配存储空间。

通常,c++会为每个对象的数据成员分配各自独立的存储空间,数据成员是分开进行存放的。成员函数代码只有一份公用的一段存储空间,调用不同对象的成员函数时都是执行同一段函数代码。

假设定义一个类

class Time {
    int h, m, s;//数据成员
    void settime(int a, int b, int c)
    { h=a,m=b,s=c;}  //成员函数
};

sizeof(Time)的值是12。Time类的存储空间长度只取决于数据成员h、m、s所占的空间,而与成员函数settime无关。c++把成员函数的代码存储在对象空间之外的地方

9、类的声明

类不能具有自身类型的数据成员。然而,只要类名一经出现就可以认为该类已声明。因此,类的数据成员可以是指向自身类型的指针或者引用。

举例:

10、对象的动态建立和释放

利用new运算符可以动态地分配对象空间,delete运算符释放对象空间。

动态分配对象的一般形式为:

类名 *对象指针变量;

对象指针变量 = new 类名;

例如:

Point *p;        //定义指向Point对象的指针变量
p = new Point;    //动态分配Point对象
delete p;    //撤销P所指向的point对象

注:

(1)用new运算动态分配得到的对象是无名的,它返回一个指向新对象的指针的值,即分配得到的对象内存单元的起始地址。程序通过这个地址可以间接访问这个对象,因此需要定义一个指向类的对象的指针变量来存放改地址。显然,用new建立的动态对象是通过指针来引用的

(2)在执行new运算时,如果内存不足,无法开辟所需的内存空间,c++编译器会返回一个0值指针。因此,只要检测返回值是否为0,就可以判断动态分配对象是否成功,只有指针有效时才能使用对象指针。

(3)new建立的动态对象不会自动撤销,即使程序运行结束也是如此,必须人为使用delete撤销

举例:

11、对象指针访问对象成员

访问对象中数据成员的一般形式为:对象指针->成员名

调用对象中成员函数的一般形式为:对象指针->成员函数(实参列表)

假设定义一个类:

12、通过引用变量访问对象中的成员

访问对象中数据成员的一般形式为:对象引用变量名.成员名

调用对象中成员函数的一般形式为:对象引用变量名.成员函数(实参列表)

如果一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值。这里所指的对象的“值”是指对象中所有数据成员的值。

(1)对象的赋值只对其中的非静态数据成员赋值,而不对成员函数赋值。

(2)如果对象的数据成员中包括动态分配资源的指针,按上述赋值的原理,赋值时只复制了指针值(地址的这个值)而没有赋值指针所指向的内容

13、对象赋值与函数的参数、返回值

如果一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值。这里所指的对象的“值”是指对象中所有数据成员的值。

(1)对象的赋值只对其中的非静态数据成员赋值,而不对成员函数赋值。

(2)如果对象的数据成员中包括动态分配资源的指针,按上述赋值的原理,赋值时只复制了指针值(地址的这个值)而没有赋值指针所指向的内容

函数的参数可以是对象、对象指针或者对象引用

(1)当形参是对象时,实参要求是相同类的对象名,c++不能对类对象进行任何隐式类型转换。实际开发不建议对象作为函数参数。

(2)当形参是对象指针时,实参要求是同类对象的指针,c++不能对对象指针进行任何隐式类型转换。采用指针传递方式,在函数中若按间接引用方式修改了形参对象本质上就是修改了实参对象。因此,使用对象指针作为函数参数可以向主调函数返回变化后的对象。

(3)当形参是对象引用时,实参要求是同类的对象,其功能与对象指针相似。

如果不希望在函数中修改实参对象的值,函数形参可以做const限定,例如:

不必对对象形参做const限定,如上述代码中的形参a,因为即使在函数中修改了a,也不会影响实参对象。

函数返回值可以时指针、对象指针或对象引用

函数返回对象时,将其内存单元的所有内容复制到一个临时对象中,因此函数返回对象时会增加开销。

函数返回对象指针或引用,本质上返回的是对象的地址而不是它的存储内容,因此不要返回局部对象的指针或引用,因为它在函数返回后是无效的。

例如:

下面是一个错误案例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值