类和对象(一)

类和对象定义

class 为类的关键字,其中类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的⽅法或者成员函数。类中可以定义函数,变量等等。

C++对C语言中的 struct 也进行了升级,升级成了类,并且同时有保留了原来的用法。

要实现一个类,一定少不了访问限定符,C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的用户使⽤。其访问限定符有三个:

而 class 和 struct 定义的类唯一差别就是:class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。

代码示例:

#include<iostream>

class Func
{
public:
	// 成员函数 / 类的方法
	int ADD(int a, int b)
	{
		return a + b;
	}
	//在类内声明,在类外实现
	void Swap(int& a, int& b);

private:
	// 成员变量 / 类的属性
	int a;
	double b;
	char c;
};

// 在类外实现,要指定类域
void Func::Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

// C++兼容C中struct的⽤法
struct ListNodeC
{
	struct ListNodeC* next;
	int val;
};

// C++改进后的用法
struct ListNodeCPP
{
public:
	void Init(int x)
	{
		next = nullptr;
		val = x;
	}

private:
	ListNodeCPP* next;
	int val;
};

int main()
{
	// Func类实例化出对象fc
	Func fc;
	fc.ADD(1, 2);

	// 设为外部不可见后,在类外访问不到a、b、c,此处会报错
	// fc.a;

	// C语言写法
	struct ListNodeC nodeC;
	// C++写法,显而易见C++写法更简便
	ListNodeCPP nodeCPP;

	return 0;
}

由上述代码也可以看到,类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤ :: 作用域操作符指明成员属于哪个类域。


隐含的this指针

看这段代码:


#include<iostream>

class Stack
{
public:
	void Init(int n = 4)
	{
		a = (int*)malloc(sizeof(int) * 4);
		capacity = 4;
		top = 0;
	}

	void Push(int x)
	{
		if (top == capacity)
		{
			int newcapacity = 2 * capacity;
			int* tmp = (int*)realloc(a, sizeof(int) * newcapacity);
			a = tmp;
			capacity = newcapacity;
		}
		a[top++] = x;
	}

	void Destroy()
	{
		free(a);
		a = nullptr;//空指针
		top = capacity = 0;
	}

private:
	int* a;
	int top;
	int capacity;
};

int main()
{
	//Stack类实例化出对象st1、st2
	Stack st1;
	Stack st2;

	st1.Init();
	st2.Init();
	st1.Destroy();
	st2.Destroy();

	return 0;
}

Stack 类中有 Init 与 Destroy 两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤ Init 与 Destroy 函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?

C++中设计了⼀个隐含的this指针来解决访问对象的问题。所以类的成员函数中访问成员变量,本质都是通过this指针访问的。

编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this 指针。所以Stack类中函数的真实原型是(注意,这种写法是错误的,编译器会报错):

#include<iostream>

class Stack
{
public:
	void Init(Stack* const this, int n = 4)
	{
		this->a = (int*)malloc(sizeof(int) * 4);
		this->capacity = 4;
		this->top = 0;
	}

	void Push(Stack* const this, int x)
	{
		if (top == capacity)
		{
			int newcapacity = 2 * capacity;
			int* tmp = (int*)realloc(a, sizeof(int) * newcapacity);
			a = tmp;
			capacity = newcapacity;
		}
		a[top++] = x;
	}

	void Destroy(Stack* const this)
	{
		free(a);
		a = nullptr;//空指针
		top = capacity = 0;
	}

private:
	int* a;
	int top;
	int capacity;
};

int main()
{
	//Stack类实例化出对象st1、st2
	Stack st1;
	Stack st2;

	st1.Init(&st1);
	st2.Init(&st2);
	st1.Destroy(&st1);
	st2.Destroy(&st2);

	return 0;
}

但C++规定不能在函数参数的位置显示的写this指针,编译器会报错(因为编译时编译器会自己处理),但是可以在函数体内显示使⽤this指针。

正确写法为:

void Init(int n = 4)
{
	this->a = (int*)malloc(sizeof(int) * 4);
	this->capacity = 4;
	this->top = 0;
}

通过调试,我们看到:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值