类和对象

一、类的定义

类是一种复杂类型,将不同的类型的数据和相关的操作封装在一起。类是对象的抽象,对象是类的一种实例。

类定义方式

将类的声明和定义放在类内。优点是编译器可以将其识别为内联函数,缺点是会出现头文件包含的问题。
将类的声明和定义分开,声明在类内,定义在类外,以便于重复利用。

二、访问限定符

类的访问限定符分为public、protected、private。

说明:

1.pubic成员可以在类外访问,protected和private成员在类外不可以访问。
2.作用域是从该访问限定符开始到下一个访问限定符出现为止。
3.class默认的访问权限是private,struct默认的访问权限是public。

三、类的作用域

C++中作用域分为:全局域、局部域、类域、名字空间域。

类成员的三种访问形式

1.直接成员运算符(.)
对象.成员变量/成员函数
2.间接成员运算符(->)
对象指针->成员变量/成员函数
3.作用域解析符(::)
常用于类的内部。

四、类的实例化

定义一个类并没有分配实际的内存空间来存储它。只有在实例化时才分配空间。

类实例化的方式

A a;
A* a1 = new A();

两者的区别:前者是在栈中分配内存,后者在堆中分配内存,一般没什么区别,但是动态分配会使对象的可控性增强。大程序用new,小程序直接申请。new最后必须delete,直接申请的空间系统会自动回收存储。

五、类的对象模型

指的是类对象各个成员变量的分布形式,类的大小由非静态成员变量相加,并考虑内存对齐。

六、this指针

this指针是类类型的引用,且被const修饰。它不是对象的一部分,不影响sizeof的结果。this指针是在成员函数调用前创建,在成员函数结束后消失。

this指针是类成员变量的第一个默认隐含参数,编译器自动维护,只有在类的非静态成员中才能使用this指针,其他函数中不能使用。

thiscall调用约定:参数是从右向左压栈的,如果参数确定,this指针通过ecx传递给调用者,如果不确定,this指针在所有参数压栈后被压入栈。对于参数不确定的,调用者清理堆栈,否则函数自己清理堆栈。

七、类的六大默认成员函数

构造函数

1.概念

名字与类名相同,创建类对象时,由编译器自动调用。在对象的生命周期只调用一次,以保证每个数据成员都有一个合适的初始值。

2.特性

* 构造函数的函数名与类名相同;
* 没有返回值;
* 有初始化列表,也可以不使用;
* 若没有显示定义,编译器会自动调用默认的构造函数;
* 无参构造函数和缺省的构造函数都属于缺省构造函数,缺省构造函数只能有一个;
* 不能用const修饰。

3.作用

* 构造对象
* 初始化对象
* 类型转换

4.调用时机

在对象被创建时调用。

5.两个阶段

(1)初始化
初始化可以在初始化列表中进行初始化,也可以在构造函数体内进行初始化。

一般情况下,初始化列表顺序是按照数据成员在类中定义顺序初始化的,如果初始化依赖于其他成员的值,要注意初始化顺序,尽量保持定义顺序初始化。

必须在初始化列表中初始化的场景:引用数据成员、const数据成员、类类型成员。

(2)普通计算阶段(赋值)
给类中数据成员进行重新赋值,会覆盖初始化成员的值。

(3)注意
* 对于普通成员,其值的设定可以放在初始化阶段或赋值阶段;
* 对于const类型的数据成员和引用数据成员,其初始化必须在初始化阶段完成;
* 引用类型变量初始化时必须使用相同的类型的变量进行初始化,不可以使用常量进行初始化。

6.默认的构造函数

如果没有显式定义构造函数,编译器会自动合成一个默认的构造函数,什么都不做。如果显式定义了,编译器不会合成默认的构造函数,最好是给一个无参的构造函数。

7.explict

用explict修饰的构造函数,不允许构造函数隐式转换。

拷贝构造函数

1.概念

只有单个形参,且是类类型的引用,一般用const修饰,编译器自动调用。

2.特性

* ​与构造函数构成重载;
* 参数是同类型对象的引用;
* 若没有显示定义,系统会合成一个默认的。

3.作用

用已存在的同类对象进行初始化。

析构函数

1.概念

在对象被销毁时,由编译器自动调用,完成类的一些资源清理工作。

2.特性

* ​在类名前加~;
* 没有参数和返回值;
* 一个类中只有一个析构函数,若无定义,系统会自动生成缺省的构造函数;
* 析构函数不是删除对象,而是做一些收尾工作。

3.作用

销毁对象时,做一些资源清理工作。

4.调用时机

在对象被销毁时,做一些清理资源的工作。

赋值运算符重载

常见的重载运算符:++、–、[]、<<
不能重载的运算符:.、.*、::、?:、sizeof

取地址运算符重载

const修饰的取地址运算符重载

八、static成员

1.概念

声明为static的类成员称为类的静态成员。分为静态成员数据和静态成员函数。

2.特性

* 静态成员被所有类对象共享,不属于某个具体的实例;
* 访问方式:类名.静态成员、对象.静态成员;
* 静态成员在对象创建前就创建了;
* 静态成员必须在类外定义,声明为static,定义时不加static关键字;
* 类的静态成员函数没有this指针、super关键字,在类的静态成员函数中不能使用非静态成员变量;
* 静态成员函数也有三种访问权限,返回值,const修饰符;
* 静态成员函数只能访问静态成员,非静态成员函数可以访问静态成员,也可以访问非静态成员。

3.静态成员与普通成员的区别

(1)生命周期
普通成员生命周期随对象,静态成员生命周期随类。
(2)调用方式
普通成员只能被对象调用,静态成员可以被对象调用,也可以被类名调用。
(3)别名
普通成员也称实例变量,静态成员也称类变量。
(4)存储位置
普通成员数据存储在内存的对象中,是对象的特有数据;
静态成员数据存储在方法区的静态区中,共享数据。

九、const修饰的成员

1.概念

const修饰的成员是一个常量,具有宏常量的特性,可以当做真正的常量。

2.使用场景

修饰形参、返回值、成员变量、成员函数等。
修饰的成员变量必须在构造函数的初始化列表中进行初始化,修饰成员函数,其实是修饰成员函数中隐含的this指针,表示在类中不可以对类的任何成员进行修改,如果要对类的某个数据成员进行修改,该数据成员声明和定义必须被mutable修饰。

3.调用规则

* const对象只能访问const成员函数;
* 非const对象可以访问const成员函数,也可以访问非const成员函数;
* const成员函数只能调用其他的const成员函数;
* 非const成员函数可以调用其他const成员函数,也可以调用其他非const成员函数。

十、内联函数

1.概念

用inline修饰的函数是内联函数。编译时,编译器在调用内联函数的地方展开,没有参数压栈,提升程序运行效率。

2.特性

* ​声明和定义必须放在一起;
* 以空间换时间,省去函数压栈开销;
* inline对编译器来说只是建议,如果函数体内有递归或循环,编译器优化时会忽略内联;
* 在类内定义的成员函数默认是内联函数,即使不加inline,也是内联函数。

3.内联函数和宏的区别

* ​内联函数是函数,宏不是函数;
* 内联函数在编译器时展开,内联函数在预处理展开;
* 内联函数是嵌入目标代码中,宏只是进行简单的文本替换;
* 内联函数有参数类型检测、语句是否正确的检查,提高了程序的安全性;
* 内联函数不会出现二义性,但是宏处理时,最好用括号括起来,避免二义性。

十一、友元

1.友元函数

友元函数定义在类外,在类内部声明上加上friend关键字。友元函数不属于任何类,可以在类定义的任何地方声明,不受类访问限定符的限制。

2.友元类

友元类的所有成员函数可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

3.友元优缺点

优点:提高了程序运行效率。
缺点:破坏了类的封装性和隐藏性。

4.友元特性

友元是单向的,不具有交换性。关系不能传递。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值