C++类和对象【1】(使用,作用域,封装等)

在学习之前我们要知道,c语言是面向过程的,分析解决问题的步骤,通过使用函数调用来解决问题。而C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。用类来描述对象,这个类就可以看作事物的抽象,因此是C++中非常重要的一个知识点是后面学习的重要基础。因此本篇文章将会详细讲解类使用及相关知识。

1.认识类

我们了解c语言可知,c结构体中只能定义变量,但在C++中不仅仅可以定义变量还可以定义函数。在数据结构体中我们用c语言取实现栈,结构体内只能存在变量,使用c++后结构体内还能定义函数。

struct acc//c语言对于结构体的命名
{
    
    
	int b;//成员
	char c;//成员
	double e;//成员
};
class  类名//c++中喜欢用class关键字进行类的定义
{
    
    
   //里面由成员函数和成员变量组成;
   public:
   
   private:
   
};

类的定义

class为定义类的关键字,Name为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。
类中内容的成为类的成员,类中的变量叫类的属性或者成员变量,类中函数称为成员函数或类的方法;

class Name
{
    
    
   public:
    //public 表示公开的属性和方法, 外界可以直接访问或调用
   private:
    //private 表示该部分内容是私密的, 不能被外部所访问或调用, 只能本类内部访问
};//;不能省略

类有两种定义方式:
1.定义和声明一起放在类中。

class add
{
    
    
public:
	void pritab()//函数声明和定义放在类中,但有可能被编译器当成内联函数处理
	{
    
    
		cout << a << b << endl;
	}
private:
	int a;
	int b;
	char c;
 };

2.将类声明放在头文件中,成员函数单独实现
声明放入practise.h头文件中
在这里插入图片描述
实现放入practise.cpp中

c++中类相当于定义了一个新的作用域,类的所有成员都在类的作用域中。这里需要注意的是在类体外定义成员时需要使用 :: 作用域操作符指明属于那个类的,这里就在在成员函数名前用 类名 + ::

在这里插入图片描述

2.访问限定符及封装

在上面的类的介绍中可以看到类中有private和public,那么这两个是什么作用?
在c++中 这是实现封装的方式。封装将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。 在C++中实现封装,通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。因此private和public为访问限定符.

访问限定符有3种
public(共有)
protected(保护)
private(私有)

访问限定符的介绍:

  1. public修饰的成员在类外可以直接被访问,没有任何限制。
  2. protected和private修饰的在类外不能直接被访问,被限制只能类里进行访问
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,中间的区域都是上面访问限定符的作用域;没有后以}为止
class add
{
    
    
public://到private为止中间为public的作用域
	void pritab(); 
private://到}为止中间为private的作用域
	int a;
	int b;
	char c;
};

那么c++中的struct与c语言中的有什么不同吗?
我们知道c++是在c语言的基础上发展的,兼容c语言,在c++中struct可以当作结构体使用,也可以当作类来使用,和class的使用方法一致,区别就是c++的struct默认访问权限是public(共有的),class为private(私有的);

3. 计算类对象的大小

在c++中一个类的大小实际就是“成员变量”之和,当然要注意内存对齐,求解方法与结构体的求解方法一样
点击查看->详细的结构体计算方法

结构体的计算方法:

  1. 第一个成员在与结构体偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    VS中默认的对齐数为8
  3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

4.this指针

我们观察下面这个代码:

class Date
{
    
    
public:
	void Init(int year, int month, int day)
	{
    
    
		_year = year;//这里的_year是d1的_year还是d2的_year?
		_month = month;//这里的_year是d1的_year还是d2的_year?
		_day = day;//这里的_year是d1的_year还是d2的_year?
	}
	void Print()
	{
    
    
		cout << _year << "-" << _month << "-" << _day << endl;//这里也是三个变量是指的谁的变量
	}
private:
	int _year; 
	int _month; 
	int _day; 
};
int main()
{
    
    
	Date d1; 
	Date d2;
	d1.Init(1010, 1, 11);
	d2.Init(5026, 1, 12);
	d1.Print();
	d2.Print();
	return 0;
}

可以看到我们并没往Init和Print函数内传d1和d2,函数体中也没有关于不同对象的区分,那么编译器是如何知道初始化赋值给谁,打印谁的数据?

对于这个问题C++是通过this指针来解决这个问题的,C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。这些都是编译器自动完成因此不需要我们自己去传递。因此this是存在栈里的是隐含形参,并不存在类里。
因此处理后的结果为

 class Date
{
    
    
public:
	void Init(Date* this,int year, int month, int day)
	{
    
    
		this->_year = year; 
		this->_month = month; 
		this->_day = day; 
	}
	void Print(Date* this)
	{
    
    
		cout <<this-> _year << "-" << this->_month << "-" <<this-> _day << endl; 
	}
private:
	int _year; 
	int _month; 
	int _day; 
};
int main()
{
    
    
	Date d1; 
	Date d2;
	d1.Init(&d1,1010, 1, 11);
	d2.Init(&d2,5026, 1, 12);
	d1.Print(&d1);
	d2.Print(&d2);
	return 0;
}

this指针特点

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

猜你喜欢

转载自blog.csdn.net/qq_64392094/article/details/129846998
今日推荐