C++ 类与对象

一、前言
C语言是面向过程的,关注的是过程,分析解决问题的步骤,逐步解决问题.
C++是面向对象的,关注的是对象,将事物拆分成多个不同的对象,靠彼此之间相互联系。

二、类的引入
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。
比如在C语言中实现栈,结构体中只能放变量,而C++中可以定义函数。
来看看区别吧。

C语言实现
struct Stack
{
	Datetype* a;
	int top;
	int capacity;	
};
void Init(size_t capacity);
void Push(const DataType& data);
C++实现
struct Stack
{
	void Init(size_t capacity)
	{}
	void Push(const DataType& data)
	{}
	Datetype* a;
	int top;
	int capacity;
};

而在C++中,更喜欢用class来代替结构体定义

三、类的定义

class classname
{
	  类成员
};这里是有分号的。

类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
类的两种构造方式:
1.在类内中实现成员函数.
例:

class Person
{
public:
	void print()
	{
		cout<<"Person类函数"<<endl;
	}
private:
	int age;
	char* name;
};

第二种定义方式:
class Person
{
public:
类内声明:
	void print();
private:
	int age;
	char* name;
};
类外实现:一定要加上作用域: Person::
void Person::print()
{
		cout<<"Person类函数"<<endl;
}
同样也可以在.h文件中声明,.cpp文件中实现。

仔细的同学已经看到了,在类的里面有public和private,那么这是什么呢?
可以理解为访问的权限,class里一共有public,protect,private.
分别代表 公共,保护,私有权限。
public:类内和类外都可以访问到.
protect:类内可以访问,类外不能访问. (子类可以访问,以后再提什么是子类)
private:类内可以访问,类外不能访问.
举个简单的例子说明成员变量和成员函数在private的权限下,类外是不可以拿到的。
在这里插入图片描述
可以看到啊,在类外的时候,是无法用到private权限下的成员函数和成员变量的.

那么有同学会问了,如果类外拿不到的话,这么定义有什么意义呢?
下面我再举个例子:
在这里插入图片描述
我们可以通过成员函数来得到成员变量的值,而不可直接访问成员变量。

可能有的同学就很有疑问了,这么做不是拉下裤子放屁,多此一举吗?
nonono,存在即合理.
举个简单例子:
在这里插入图片描述
对于栈,我们再熟悉不过了,获取栈顶元素也是我们经常做的。
那么top1和top2的获取方式是不一样的。
top1的方式是知道top的初始值.因为我们在定义的时候通常会选择将top初始值选择为0或者-1.
top2的方式是通过成员函数来获取的。
假设我们不知道top的初始值,我们如果盲目选择top1的获取方式,那么是容易出错的,数组越界或者取值不对。

四、类的实例化
什么是类的实例化呢?可以理解为,用这个类创建对象。
例:
在这里插入图片描述
这里的s1便是创建出来的对象,也就是类的实例化。概念十分简单。

五、this指针

class Data
{
public:
如果形参和成员变量是相同的名称会发生什么情况呢?
答案是 成员变量不会被赋值
	Data(int year, int month, int day)
	{
		year = year;
		month = month;
		day = day;
	}
如何解决这样的情况?加上this指针。
	Data(int year, int month, int day)
	{
		this->year = year;
		this->month = month;
		this->day = day;
	}
private:
	int year;
	int month;
	int day;
};
int main()
{
	Data d1(2022, 2, 2);
	return 0;
}

那么this指针的原理是什么呢?
其实在调用成员函数的时候,this指针被隐藏起来了。
实际情况是这样的:

Data(Data * const this,int year, int month, int day)
	{
		this->year = year;
		this->month = month;
		this->day = day;
	}
	thisconst修饰,因此this不能被改变。

5.1 this指针的特性

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

5.2常见的关于this指针的面试问题

  1. this指针存在哪里?
  2. this指针可以为空吗?

1 this指针存在哪里呢?
成员函数的其它参数正常都是存放在栈中。
而this指针参数则是存放在寄存器中。

2 this指针当然可以为空

来看这样一段代码
class A
{
public:
	void Print()
	{
		cout << "Print()" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}
运行结果会是怎样?
A、编译报错 B、运行崩溃 C、正常运行
答案是C.
原因是因为 调用Print函数的时候
其原理是 Print( A *const this).
而函数里的内容并没有对this进行解引用,因此不会报错.

再看下面这个例子
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
return 0;
}
运行结果会是怎样?
A、编译报错 B、运行崩溃 C、正常运行
答案是 B
同理如上,调用Print函数的原理是:
Print(A* const this)
而函数内部的_a,this->_a;this指针进行了解引用,因此会运行崩溃。
明白了吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值