😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
⏰发布时间⏰:2024-05-30
本文未经允许,不得转发!!!
目录
- 🎄一、概述
- 🎄二、C++中的类
- ✨2.1 类将数据和函数组织在一起
- ✨2.2 类的访问控制(public、private、protect)
- ✨2.3 实现类成员函数
- 🎄三、对象(实例)
- 🎄四、类作用域
- ✨4.1 类作用域中的常量
- 🎄五、总结
🎄一、概述
C++是面向对象编程的语言,编写C++代码是以类的形式来组织代码的,然后实例化一个个对象,让对象之间的交互来完成要做的事情。本文主要介绍C++中的自定义类型——类,以及怎么使用类去构建对象。
既然类是一种自定义类型,那么我们先了解一下什么是类型。类型主要完成下面三项工作:
- 1、决定该类型的变量(对象)占用多少字节的内存:
例如:int
类型占用4个字节;short
类型占用2个字节;char
占用1个字节。 - 2、决定怎样解释内存中的数据;
例如:内存中存放着0xff
这个数据,int
类型和char
类型对0xff
的解释是不同的。 - 3、决定该类型的变量(对象)可以执行哪些操作:
例如:int
类型的变量可以执行加减乘除等操作;而int*
类型的变量一般不会执行乘法、除法的操作。
下面的内容将介绍类和对象。
🎄二、C++中的类
类是一种将抽象转换为用户定义类型的 C++工具, 它将数据表示和操纵数据的方法组合成一个整洁的包。
✨2.1 类将数据和函数组织在一起
如果你之前学过C语言,那么可能会觉得类
和结构体
会有点类似,它可以将多个数据组织在一起,但不同于C语言的结构体,类成员除了数据还可以是函数。定义一个类,可以使用class
关键字。
class Animal
{int legs;int eye;void run(){cout << "Animal run" << endl;}
};
上面代码定义了一个类,将数据和函数放在同一个类中。
✨2.2 类的访问控制(public、private、protect)
类的成员有三种访问控制(public、private、protect),它们代表的含义如下:
1、public
:标识的类成员公有的,这个类的对象可以直接访问;
2、private
:标识的类成员私有的,这个类的对象不能直接访问,可以通过该类的公有成员间接地访问;
3、protect
:标识的类成员受保护的,这个类的对象不能直接访问,可以通过该类的公有成员或该类的子类成员间接地访问。
另外注意一点,在C++中,类的默认访问控制权限是private
的,结构体的默认访问控制权限是public
的。所以前面小节定义的Animal类的几个成员都是私有的。虽然类的默认访问权限是private
的,但为了强调数据隐藏的概念,还是建议显示地使用private
关键字。
面向对象的一个特性就是封装,也就是数据隐藏和隐藏实现细节。所以,一般情况下,数据项通常放在私有部分(数据隐藏),实现细节相关的函数也放在私有部分(隐藏实现细节),而组成类接口的成员函数放在公有部分。
有了这些认识,我们对上个小节的 Animal 类做个小调整,
class Animal
{
private:int legs;int eye;public:void run() // 公有接口{cout << "Animal run" << endl;}
};
✨2.3 实现类成员函数
类成员函数一般在定义类时声明,然后将函数实现写在类定义之外。
类成员函数的几个特征:
-
1、定义成员函数时,使用作用域解析运算符(
::
)来标识该成员函数所属的类,例如 run() 成员函数头如下:void Animal::run()
这种表示法意味着
run()
是Animal
类的成员,还意味着我们可以将另一个类的成员函数命名为run()
;
类成员函数的完整名称包括类名,而简单的run()
是全名的缩写,只能在类作用域中使用。 -
2、类成员函数可以访问类的 private 成员。
class Animal{ private:int legs;int eye; public:int legs() // 公有接口{return legs;} };
-
3、定义位于类声明中的函数都将自动成为内联函数。如下面的
run()
函数会自动成为内联函数:class Animal{ ... public:void run() // 公有接口{cout << "Animal run" << endl;} };
一般会将类声明放在头文件中,而将类成员函数实现放在源文件中,看下面例子:
#ifndef __ANIMAL_H__
#define __ANIMAL_H__#include <iostream>
using namespace std;class Animal
{
private:int legs;int eye;public:void run() // 公有接口{cout << "Animal run" << endl;}void SetLegs(int _legs);int GetLegs();
};#endif //__ANIMAL_H__
// g++ 08_Animal.cpp#include "08_Animal.h"void Animal::SetLegs(int _legs)
{legs = _legs;
}int Animal::GetLegs()
{return legs;
}int main()
{Animal animal;animal.run();animal.SetLegs(4);cout << "animal legs = " << animal.GetLegs() << endl;return 0;
}
🎄三、对象(实例)
类是用户自定义的类型,对象(如变量)是类的实例。
之前学习C语言时,通过类型定义出来的被成为变量。在面向对象编程中,通过类型(包括自定义类型)定义出来的被成为对象
。
例如下面的i、s、cAnimal
都是对象:
int i = 0;
short s = 0;
Animal cAnimal; // Animal类的对象
注意:所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。
为什么需要对象?
就像C语言需要变量一样,我们定义了一个类,需要通过对象(实例)来使用这个类。
C++的目标是使得使用类与使用基本的内置类型( 如 int 和 char ) 尽可能相同。
怎么创建对象?
Animal cAnimal; Animal *pAnimal = new Animal();
如上面代码,要创建类对象, 可以声明类变量, 也可以使用 new 为类对象分配存储空间。
怎么使用对象?
Animal cAnimal; Animal *pAnimal = new Animal(); cAnimal.run(); pAnimal->run();
要使用新类型, 最关键的是要了解成员函数的功能, 而不必考虑其实现细节。
如上代码,定义了对象后,可以使用 成员运算符(.
和->
)来调用类的公有成员。
🎄四、类作用域
C++类引入了一种新的作用域: 类作用域
在类中定义的名称(如类数据成员名和类成员函数名)的作用域都为整个类,作用域为整个类的名称只在该类中是已知的, 在类外是不可知的。因此,可以在不同类中使用相同的类成员名而不会引起冲突。
另外, 类作用域意味着不能从外部直接访问类的成员,公有成员函数也是如此。也就是说,要调用公有成员函数,必须通过对象。
总之,在类声明或成员函数定义中,可以使用未修饰的成员名称(未限定的名称),如上面例子直接使用run()
;在其他情况下, 使用类成员名时, 必须根据上下文使用直接成员运算符(.
)、 间接成员运算符(->
) 或作用域解析运算符(::
)。
下面的代码片段演示了如何访问具有类作用域的标识符:
#include <iostream>
using namespace std;class Animal
{
private:int legs;int eye;public:void run(){cout << "Animal run" << endl;}void SetLegs(int _legs);int GetLegs(){return legs;}
};void Animal::SetLegs(int _legs)// 作用域解析运算符(`::`)
{legs = _legs;
}int main()
{Animal animal;animal.run(); // 直接成员运算符(`.`)Animal *pAnimal = new Animal();pAnimal->run(); // 间接成员运算符(`->`) return 0;
}
✨4.1 类作用域中的常量
如果想在类中使用一个常量,直接使用下面代码是行不通的:
class Date
{
public:const int Month_C = 12; // 报错:invalid use of non-static data member ‘Date::Month_C’int mon_const[Month_C];
};
因为声明类只是描述了对象的形式,并没有创建对象,在创建对象前, 将没有用于存储值的空间。
可以使用下面两个方法在类中声明常量:
- 1、在类中声明一个枚举:
在类中声明一个枚举并不会创建数据成员,所以也不需要对象的存储空间。代码如下:class Date { public:enum {Month_E = 12};int mon[Month_E]; };
- 2、使用关键字
static
,定义属于整个类的常量:
下面代码将创建一个名为 Month_C 的常量,该常量将与其他静态变量存储在一起,而不是存储在对象中。该常量被所有Date
对象共享。class Date { public:static const int Month_C = 12; // 报错:invalid use of non-static data member ‘Date::Month_C’int mon_const[Month_C]; };
上面例子完整代码:
#include <iostream>
using namespace std;class Date
{
public:enum {Month_E = 12};//const int Month_C = 12; // 报错:invalid use of non-static data member ‘Date::Month_C’static const int Month_C = 12; // 属于整个类int mon[Month_E];int mon_const[Month_C];
};int main()
{Date date;cout << Date::Month_E << endl;cout << Date::Month_C << endl;cout << "Date=" << sizeof(Date) << "date="<< sizeof(date)<< endl;return 0;
}
运行结果如下,整个类的大小为96,可以看出这两种方法都不会占用到类的空间。
🎄五、总结
👉本文简单介绍C++中类的访问控制、实现成员函数、对象的创建和使用、类作用域、类作用域的常量等知识点。
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁
参考:
《C++ priper plus》