C++初阶语法——类和对象

前言:C语言中的结构体,在C++有着更高位替代者——类。而类的实例化叫做对象。
本篇文章不定期更新扩展后续内容。

目录

  • 一.面向过程和面向对象初步认识
  • 二.类
    • 1.C++中的结构体
    • 2.类的定义
      • 类的两种定义方式
    • 3.类的访问限定符及封装
      • 访问限定符说明
    • 4.类的实例化
      • 对象只存储成员变量,不存储成员函数
      • 成员函数存储在公共代码区
    • 5.this指针

一.面向过程和面向对象初步认识

在学习C语言的时候,我就时常听说过面向过程和面向对象,但是对这两个概念的认知非常模糊,那么这两者有什么区别呢?

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
而C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。我们不需要关注过程是怎么完成的,我们只需要关注对象间的交互。
面向对象有3大特性——封装,继承,多态。

二.类

1.C++中的结构体

C语言中结构体中只能定义变量,而在C++中,结构体中不仅能定义变量,还可以定义函数(struct升级成了类)。

以数据结构——栈为例:
直接在结构体内定义函数。
实例化对象时,无需再写struct,只需写结构体名。

#include
using namespace std;
typedef struct Stack {
	int* a;
	int capacity;
	int top;
	void Init()   //定义函数
	{
		a = nullptr;
		capacity = 0;
		top = 0;
	}
}ST;
int main()
{
	Stack s1; // 无struct
	s1.Init();
	return 0;
}

2.类的定义

在C++中,类更喜欢用class而非struct。
这两者在默认访问限定上有些区别,struct默认为public,而class默认为private,更符合面向对象的要求。这也是为什么更喜欢使用class。该点在下文默认访问限定符也会讲解。

class Classname
{
	//类体:成员函数+成员变量

};  //跟结构体一样有分号不要忘

class为定义类的关键字,Classname为类名,{}中为类的主体,类体中的内容称为类的成员,类中的变量称为类的属性或成员变量,类中的函数称为类的方法或成员函数。

类的两种定义方式

一种就是向上面的栈一样将函数声明定义都写在类里面,值得一提的是,这种函数会被编译器当成内联函数。
还有一种就是将类声明放在头文件中,在源文件中定义函数,但是需要注意的是,成员函数名前需要加类名::(域作用限定符),一般第二种用的更多。

//obj.h
#include
using namespace std;

typedef struct Stack {
	int* a;
	int capacity;
	int top;
	void Init();
}ST;

//test.cpp
#include"obj.h"
void Stack::Init()  // 类名::
{
	a = nullptr;
	capacity = top = 0;
}

3.类的访问限定符及封装

C++实现封装的方式:用类将对象的属性(成员变量)和方法(成员函数)结合在一起,让对象更加完善,通过访问限定符选择性的将其接口提供给外部的用户使用。

共有3种访问限定符:在诸如php,java等语言中都有。
C++初阶语法——类和对象_第1张图片

访问限定符说明

利用好访问限定符,可以有效保护好类中的数据,防止其他人随便访问。
1.public:公有的类成员可以在任何地方被访问。
protect:受保护的类成员则可以被其自身以及其子类和父类访问。
private:私有的类成员则只能被其定义所在的类访问。
(在学继承之前,protect和private使用起来没差)
2.struct默认为public,class默认为private。
3.访问权限作用域从该访问限定符开始到下一个访问限定符出现。
4.如果后面没有访问限定符,作用域到 } 为止。
5.一般情况下,成员变量都设置为private。

以日期类为例:

class Date {
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;  //声明,没有定义,不占空间
	int _month;
	int _day;
};

4.类的实例化

用类创建对象的过程,叫做类的实例化。
1.类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它。
2.一个类可以实例化出多个对象。实例化出的对象才占用实际的内存空间,且只存储成员变量,不存储成员函数。

以日期类为例:

class Date {
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;  //声明,没有定义,不占空间
	int _month;
	int _day;
};

int main()
{
	
	Date d1;  // 类的实例化
	Date d2, d3;  // 一个类可以实例化出多个对象
	//下面两行代码可行吗,为什么?
	//Date::_year = 1;  //并没有实例化对象,只是声明没有开空间,更不必说初始化了。
	//d1._year = 1; //实例化了呢?也不行,因为_year是私有成员变量,只能在Date类中更改。
	return 0;
}

对象只存储成员变量,不存储成员函数

上文说过,类的主体有两个:成员变量和成员函数。
但实际上实例化的对象中只存储成员变量,而成员函数存储在公共代码区。

请看下例代码(类的空间大小计算和结构体一样,遵循结构体内存对齐规则):

class Date {
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;   //声明,没有定义,不占空间
	int _month;
	int _day;
};

int main()
{
	Date s1;
	cout << sizeof(Date) << endl;
	cout << sizeof(s1) << endl;
	return 0;
}

控制台输出如下:
C++初阶语法——类和对象_第2张图片
可以发现,12是只计算成员变量得到的结果,因此可以得知对象中并不存储成员函数。

之所以这样是因为成员函数对每个对象都是一样的,其会被存储在公共代码区,这样不必要在每次实例化对象时都存储一次成员函数,大大提高了程序效率。
C++初阶语法——类和对象_第3张图片

成员函数存储在公共代码区

请看如下代码,各位觉得能够运行成功吗?

class Example
{
public:
	void Print()
	{
		cout << "Print()" << endl;
	}
private:
	int _a;
	int _b;
};
int main()
{
	Example* s1 = nullptr;
	s1->Print();  //空指针指向????
	return 0;
}

控制台显示如下:
在这里插入图片描述
运行成功了,为什么呢?上面不是空指针解引用问题吗,程序应该崩溃呀?
答:上面说过成员函数存储在公共代码区,直接向公共代码区call该函数的地址,不需要向对象s1中找东西,因此不会发生空指针解引用操作。

5.this指针

类的成员函数中都隐藏了一个this指针参数。
this在实参和形参位置不能显示写,但是可以在类里面显示的用。
this指针不可被更改.

仍以日期类为例:

class Date {
public:
	//this在实参和形参中不能显示地写
	//在类中可以显示地用(没什么价值)
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	/*void Init(Date* const this ,int year, int month, int day)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}*/
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;
	d1.Init(2023, 8, 11); //d1.Init(&d1,2023,8,11);
	return 0;
}

你可能感兴趣的:(C++基础语法,c++,开发语言,c,c语言,visualstudio)