[C++]---类和对象(一){一:类和对象初步了解 二:类的引入与定义 三:类的访问限定符 四:类对象存储模型 五:this指针}

目录

一:类和对象初步了解

类和对象关系:

类与类的实例化

二:类的引入与定义

C++如何定义类?

类的两种定义方式:

三:类的访问限定符

分类:

作用:

特点:

如何类外访问类的成员

四:类对象存储模型

两种类对象存储模型假设

验证类存储方式:

五:this指针

this指针的特性:

this指针的两个小问题:


一:类和对象初步了解

C语言是面向过程的,关注的是过程,解决问题一般是分析解决问题步骤,然后通过调用函数逐步解决问题.

C++是面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

类和对象关系:

类是对象的抽象,对象是类的实例化.

类与类的实例化

eg:

二:类的引入与定义

在C++中类的引入依靠的是C语言中的结构体,因为结构体这种类型可以包含不同种数据类型,极大的满足了类中对象的不同属性。

C++如何定义类?

class className
{
    // 类体:由成员函数和成员变量组成
}; // 分号不可省略  className:类名

C++中一般使用的是class这个关键字进行类的定义,其实C语言中的struct也可以用来定义类.定义方法完全相同.

struct和class定义类区别:(对类成员的默认访问方式或者说是权限不同

1.默认继承权限,如果不指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;

2.成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。

因此,C++中一般建议使用class这个关键字用来定义类.

类的两种定义方式:

1.类的声明和定义都放在类体中.(注意成员函数放在里面可能会被编译器当做内联函数进行处理)

2.在 C++ 实际编程时,分别使用.h 和.cpp 来定义一个类。

  • .h 中存放类的声明,函数原型(放在类的声明中)。
  • .cpp 存放函数体。

如果我们在一个头文件里声明了一个函数,当我们需要定义这个函数(这个定义是唯一的,也就是只能定义一次),或者需要使用这个函数时,我们在 cpp 中需要 include 这个头文件。

一般情况下建议使用第二种

三:类的访问限定符

分类:

  1. public(公有)
  2. private(私有)
  3. protected(保护)

作用:

数据封装是面向对象编程的一个重要特点,C++作用限定符的作用:限制类外函数直接访问类类型的内部成员.

特点:

  1. public修饰的成员在类外都是直接可以被访问的.
  2. protected 和private修饰的成员在类外是不可被直接访问的.
  3. 访问限定符的作用是一个访问限定符开始出现位置到下一个访问限定符之间.
  4. struct定义的类的默认访问权限为公有(兼容C语言),而class定义的类的默认访问权限为私有(体现C++ 的封装性)

如何类外访问类的成员

在类体外定义成员,需要使用  ::   作用域解析符指明成员属于哪个类域。

class Student
{
public:
    void Show();
    void SetInfo(const char* name, const char* sex, int age);
    char _name[10];//姓名
    char _sex[5];//性别
    int   _age;//年龄
};

void Student::Show()    //Show函数是属于Student的类域
{
    cout << _name << " " << _sex << " " << _age << endl;
}
void Student::SetInfo(const char* name, const char* sex, int age)//SetInfo函数是属于Student的类域
{
    strcpy(_name, name);
    strcpy(_sex, sex);
    _age = age;
}

四:类对象存储模型

两种类对象存储模型假设

上图是一个类对象的存储结构示意图,那么当程序中要创建多个类,该如何存储嘞?

假设存储方式一:

缺陷: 每个对象中成员变量是不同的,但是调用同一份函数,如果按照此种方式存储,当一个类创建多个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间。

可以看出第二种方法采用了:只保存成员变量,成员函数存放在公共的代码段

优点:很好的避免了空间浪费.

验证类存储方式:

#include <iostream>
using namespace std;
//默认对齐数为8
class A1
{
public:
	void Fun1()
	{}
	void Fun2()
	{}
private:
	char B;//0
	int A;//4-7
	double C;//8-15    16
};  

//类中仅含有成员函数
class A2
{
public://1 标识A2类的存在
	void Fun2()
	{}
};   

//空类
class A3
{  //1 标识A3类的存在
}; 
class A4
{
public:
	char B; //0
	double  C;//8-15
	int A;  //16-19     24
}; 

//类的嵌套
class A5
{
public:
	char B;//0
	double C;//8-15
	int A;//16-19
private:
	A4 a;//从24开始:24-47    最终:48
};



#pragma pack (4)//修改默认对齐数为4
class A6
{
public:
	char B; //0
	double  C;//4-11
	int A;  //12-15        16
};
#pragma pack ()//恢复原来编译器默认对齐数
//类的嵌套
class A7
{
public:
	char B;//0
	double C;//8-15
	int A;//16-19
private:
	A6 a;//默认对齐数修改为4之后:从24开始  24-39     最终:40
};
int main()
{
	cout << sizeof(	A1) << endl;//16
	cout << sizeof(A2) << endl;//1  成员函数不占大小,相当于空类所以大小仍为1,起标识类作用
	cout << sizeof(A3) << endl;//1  空类大小为1,起标识作用
	cout << sizeof(A4) << endl;//24
	cout << sizeof(A5) << endl;//48
	cout << sizeof(A6) << endl;//16
	cout << sizeof(A7) << endl;//40
	return 0;
}

结论:一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。

以上结构体大小计算,与C语言中的结构体自动对齐中大小计算方法一致,可以参考  链接

五:this指针

C++编译器给每个“成员函数“增加了一个隐藏的指针参数即(this指针),让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。

this指针的特性:

  1.  this指针的类型:类类型* const
  2. 只能在“成员函数”的内部使用
  3.  this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
  4. this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递.

this指针的两个小问题:

1.this指针存放在哪里?

this指针只存在于类的成员函数内,而函数的生成都会开辟栈,因此在上.当然为了提高访问效率有的编译器还会做优化将它存放在寄存器内.(对计算机各部访问效率:寄存器>缓存>内存>外存)

2.this指针可以为空吗?

可以为空,当我们在调用函数的时候,如果函数内部并不需要使用到this,也就是不需要通过this指向当前对象并对其进行操作时才可以为空(当我们在其中什么都不放或者在里面随便打印一个字符串,数字),但如果调用的函数需要指向当前对象,并进行操作,则会发生错误(空指针引用)就跟C中一样不能进行空指针的引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值