C++ 类与对象(上)

时间:2024-10-24 19:32:19

何谓类与对象       

在C++中,类是一种数据类型,类似于C语言中的struct定义结构体。

       那么什么是对象呢?对象其实是类的类型实例化,就如我声明了一个栈,然后用栈的声明创建了一个栈,被创建的这个栈就是对象。

       类其实是对象的一种抽象描述,类似于一张施工的图纸,图纸上画了这个工程有什么东西,但是这张图纸上的内容在真实世界中并没有真实的东西,需要现实的人们根据图纸在现实世界创造出图纸里面的内容。这样解释类与对象的关系应该就很明确了:类是一张图纸,对象是根据图纸创造的实物。

对于类的定义,以class为关键字,后面加类名,{}中的内容为主体,与C语言结构体一样,{}后面要加分号(;)。

对于类的内容,我们称为类的成员:类的变量称为成员变量或类的属性,类中的函数称为成员函数或类的方法。

下面我们用类来实现一个栈:

class stack {
public:
	void Inint(int n = 4) {
		arr = (int*)malloc(sizeof(int) * n);
		if (arr == nullptr) {
			perror("malloc fail:");
			exit(-1);
		}
		top = 0;
		capacity = n;
	}
	void push(int x) {
		//判断栈容量是否足够,不够扩容
		if (top == capacity) {
			int newcapacity = 2 * capacity;
			int* tmp = (int*)malloc(sizeof(int) * newcapacity);
			arr = tmp;
			capacity = newcapacity;
		}
		arr[top++] = x;
	}
private:
	int* arr;
	int top;
	int capacity;

};

可以看到,类将对象的属性与方法结合在一起,并通过访问限定符封装起来,这样就可以选择性的将接口给外部用户使用而不影响到对象本身。

与C语言实现的栈相比,栈的代码能更加的直观,同时代码的安全性也有了进一步的提高。

访问限定符

在C++中访问限定符有三个,分别是:public,private,  protected,它们限制了用户的访问权限

被public修饰的成员,在类外可以直接被访问

被private和protected修饰的成员不能在类外直接访问

 相信下面的代码能让你对访问限定符有更清晰的理解:

using namespace std;
class Date {
public:
	void Init(int year, int month, int day,int now) {
		_year = year;
		_month = month;
		_day = day;
		_now = now;
	}
	void Print() {
		cout << _year << " " << _month << " " << _day <<" "<<_now<<endl;
	}
	
private:
	int _year;
	int _month;
	int _day;
protected:
	int _now;
};
int main() {
	Date d1;
	d1.Init(2024, 1, 1, 1024);
	d1.Print();
}

通过代码可以看到,private和protected修饰的变量只能在类内直接访问,public修饰的变量能在类外被访问

 对象大小

       类实例化出的每个对象,都有独立的数据空间,但是在对象独立的数据空间中,只包含成员变量,不包含成员函数,成员函数都放在了公共代码区。

       为什么对象的成员函数都放在公共代码区呢?试想,我们根据实例化实例化1000个对象,内存为每个对象都开辟独立的数据空间,但是对于成员函数,每个对象都是重复的,如果将成员函数都存储在各自的数据空间,假设每个对象都有2个成员函数,那么是不是在所有独立数据空间中总共存有2000条成员函数,但是我们想调用成员函数时,只需要一个成员函数拿来调用即可。

对于对象大小,与C语言中结构体大小计算规则一致:

第一个成员在与结构体偏移量为0处

其他成员要对齐到对齐数的整数倍地址处

VS中默认对齐数为8

对齐数=默认对齐数与一个成员大小比较的最小值

总大小应该是最大对齐数的整数倍处

 

this指针 (注意,this指针是形参,是变量,存放在栈区)

       在一个类中,对不同对象并没有做区分,那么当我们实例化多个对象时,函数是如何知道该访问哪个对象?

       其实,在编译器编译后,类的成员函数会默认在形参第一个位置加上一个当前类型的指针,叫做this指针,this指针会自动指向当前要访问的对象;在类的成员函数中访问成员变量其实也是通过this指针访问

      this指针是C++编译器默认加上去的,所以我们不能在 实参 和 形参的位置显示写this指针,但是可以在函数体内显示使用

using namespace std;
class Date {
public:
	//函数形参this指针不能显示使用
	//void Init(Date* const this, int year, int month, int day, int now)
	void Init(int year, int month, int day,int now) {
		this->_year = year;
		this->_month = month;
		this->_day = day;
		this->_now = now;
	}
	void Print() {
		cout << _year << " " << _month << " " << _day <<" "<<_now<<endl;
	}
	
private:
	int _year;
	int _month;
	int _day;
protected:
	int _now;
};
int main() {
	Date d1;
	d1.Init(2024, 1, 1, 1024);
	d1.Print();
	
}