C++类和对象(上)
1.面向过程和面向对象初步认识
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
2.类的引入
- C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。
- 类:用来对实体(对象)进行描述的,对象有什么属性,以及对象具有什么功能
是一种自定义类型 - 对象:现实生活中实实在在存在的对象是对类的具体的体现
用类类型创建出来的变量---->对象
3.类的定义
class className
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
有以下两种方式
方式一:将类的声明和定义全部放在类中定义
方式二:头文件中放类的声明在源文件放类的定义-----都采用方式二定义类
4.类的作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员,需要使用 :: 作用域解析符
指明成员属于哪个类域。
class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
cout<<_name<<" "_gender<<" "<<_age<<endl; }
5.类的实例化
用类类型创建对象的过程,称为类的实例化
- 类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它
- 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
- 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什
么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占
用物理空间
如图:
代码举例:
class Person{
public:
//显示基本信息
void showinfo();
public:
char* _name;
char* _sex;
int _age;
};
void Test(){
Person man;
man._name="jack";
man._age=10;
man._sex="男";
man.showinfo();
}
6.类的访问限定符及封装
面向对象的三大特征:封装、继承、多态(四大特性就加上:抽象)
- 封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行
交互(函数就是一种封装),如图:
访问权限:
struct定义的类:成员默认的访问权限是public
calss定义的类:成员默认的访问权限private
7.类的对象大小的计算
// 类中既有成员变量,又有成员函数
class A1 {
public:
void f1(){}
private:
int _a;
};
// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类
class A3
{};
发现: a1 a2 a3就在同一个地址的位置表明: a1、a2、a3就成为同一个对象了,这样就和a1 a2 a3实际矛盾了实际上a1 a2 a3是不同的对象,对于A2、A3这种特殊的类(没有成员变量),编译器为了区分同一个类创建出的不同的对象,主流编译器中:给A2和A3分配了1个字节
一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。
结构体内存对齐规则:
- 第一个成员在与结构体偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
- 注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8
- 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是
所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
8.类成员函数的this指针
C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有 成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
特性:
- 1. this指针的类型:类类型* const
- 2. 只能在“成员函数”的内部使用
- 3. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
- 4. this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户
传递
9.内联函数
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,引入内联函数的目的是为了解决程序中函数调用的效率问题,提升程序运行的效率。译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。这其实就是个空间代价换时间的i节省。所以内联函数一般都是1-5行的小函数。
注意:1.在内联函数内不允许使用循环语句和开关语句;
2.内联函数的定义必须出现在内联函数第一次调用之前;
3.类结构中所在的类说明内部定义的函数是内联函数