【027】C++类和对象的基本概念:封装、定义、设计与实现

引言


💡 作者简介:专注分享高性能服务器后台开发技术知识,涵盖多个领域,包括C/C++、Linux、网络协议、设计模式、中间件、云原生、数据库、分布式架构等。目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。
💡 公众号:Lion 莱恩呀

👉
🎖️ CSDN实力新星、专家博主,阿里云博客专家、华为云云享专家
👉
🔔 专栏介绍:从零到c++精通的学习之路。内容包括C++基础编程、中级编程、高级编程;掌握各个知识点。
👉
🔔 专栏地址:C++从零开始到精通
👉
🔔 博客主页:https://blog.csdn.net/Long_xu


🔔 上一篇:【026】C++的内联函数、函数重载、函数的默认参数与占位参数
🔔 下一篇:【028】C++ 类和对象的 构造函数、析构函数、拷贝构造、初始化列表 详解(最全讲解)

一、类的封装性

C++中的类封装性是指将数据和操作封装在一个单独的实体(类)中,防止外部代码直接访问对象的数据。类中的成员变量可以被声明为私有(private),以便只能通过类内部的函数来访问它们。

封装提供了以下优点:

  1. 数据隐藏:类的使用者无法直接访问私有成员变量,从而保护了数据。

  2. 可控制性:只公开必要的函数接口,可以减少不正确使用或更改数据造成的风险。

  3. 简化编程:由于用户不能直接更改数据,因此可以简化编写复杂程序时需要处理大量状态信息的过程。

  4. 提高安全性:由于私有成员变量无法直接访问,因此可以提高程序的安全性并避免未经授权对重要数据进行修改或破坏。

类将具有共性的数据和方法封装在一起,加以权限区分,用户只能通过公共方法访问私有数据。
类的权限分为:

  • private:私有。
  • protected:保护。
  • public:公共。

在类的外部,只有public修饰的成员才能访问,在没有涉及继承与派生时,privateprotected是同等级别的,外部不允许访问。用户在类的外部可以通过public的方法间接访问privateprotected数据。

访问属性属性对象内部对象外部
public公共可以访问可以访问
protected保护可以访问不可访问
private私有可以访问不可访问

二、定义一个类

定义类的时候系统不会为其开辟内存空间,只有当在类的外部实例化一个对象才会为其开辟空间;所以不要给类中的成员初始化。在类的内部不存在权限之分,只有在类外部才涉及权限划分,在定义类时如果没有指定权限修饰符则默认是private

类是一个抽象的概念,类是一个类型。

定义一个类的格式:

class 类名{
private:
	// 成员变量和成员函数
protected:
	// 成员变量和成员函数
public:
	// 成员变量和成员函数
	
};

示例:

#include <iostream>
using namespace std;
class Data{
// 类中默认私有
private:
    // 成员变量和成员函数
	int a;//不要给类成员初始化
protected:
	// 成员变量和成员函数
	int b;//不要给类成员初始化
public:
	// 成员变量和成员函数
	int c;//不要给类成员初始化
	// 在类的内部没有权限之分
	void printData() {
		a=100;
		b=200;
		c=300;
		cout<<a<<" "<<b<<" "<<c<<" "<<endl;
	}
	
	
};

int main()
{
	// 实例化一个对象
	Data obj;
	// 类外不能访问类的私有数据和保护数据
	// obj.a=100;//error
	// obj.b=100;// error
	
	obj.c=300;//ok
	// 类中的成员函数需要对象调用
	obj.printData();
	return 0;
}

三、设计一个类

设计一个类的步骤:

  1. 思考类有哪些数据成员。
  2. 操作这些数据的成员函数有哪些。
  3. 数据设为私有,成员函数设置为共有。

3.1、示例一:设计一个Person类

比如 设计一个person类,具有nameage属性,提供初始化函数、对name读写的函数以及对age读写的函数;但是需要确保age的赋值有效范围是(0~100),超出有效范围则拒绝赋值,并提供方法输出nameage

#include <iostream>
using namespace std;
#define STR_LEN		32
class Person {
	// 类中默认私有
private:
	// 成员变量和成员函数
	char mName[STR_LEN];//不要给类成员初始化
	int mAge;

public:
	// 在类的内部没有权限之分
	void PersonInit(const char *name,int age)
	{
		if (name == NULL)
			cout << "名字不能为空" << endl;
		else
			strncpy(mName, name, STR_LEN);
		
		if (age > 0 && age <= 100) 
			mAge = age;
		else
			cout << "输入的age:" << age << "不合法" << endl;

	}
	// 设置mName
	void setName(const char* name)
	{
		if (name == NULL)
			cout << "名字不能为空" << endl;
		else
			strncpy(mName, name, STR_LEN);
	}
	// 获取mName
	char *getName()
	{
		return mName;
	}
	// 设置mAge
	void setAge(int age)
	{
		if (age > 0 && age <= 100)
			mAge = age;
		else
			cout << "输入的age:" << age << "不合法" << endl;
	}
	// 获取mAge
	int getAge()
	{
		return mAge;
	}
	// 显示mName和mAge
	void show()
	{
		cout << "名字:" << mName << ",年龄:" << mAge << endl;
	}
};

int main()
{
	// 实例化一个对象
	Person obj;
	obj.PersonInit("Long",20);
	obj.setName("Lion");
	obj.setAge(18);
	cout << "名字:" << obj.getName() << ",年龄:" << obj.getAge() << endl;
	
	obj.show();
	return 0;
}

输出:

名字:Lion,年龄:18
名字:Lion,年龄:18

这个过程由对象完成相关动作,面向对象编程。

3.2、示例二:设计一个Cube类

设计一个立方体类(Cube),求出立方体面子和体积,分别用全局函数和成员函数判断两个立方体是否相等。
在这里插入图片描述

  • 立方体的面积: 2 × a × b + 2 × a × c + 2 × b × c 2\times a\times b+2\times a\times c+2\times b\times c 2×a×b+2×a×c+2×b×c
  • 立方体的体积: a × b × c a\times b\times c a×b×c
#include <iostream>
using namespace std;
#define STR_LEN		32
class Cube {
	// 类中默认私有
private:
	// 成员变量和成员函数
	int mLength;
	int mWidth;
	int mHeight;

public:
	// 在类的内部没有权限之分
	void CubeInit(int L,int W,int H)
	{
		mLength = L;
		mWidth = W;
		mHeight = H;

	}
	// 设置
	void setLength(int L)
	{
		mLength = L;
	}
	// 获取
	int getLength()
	{
		return mLength;
	}
	// 设置
	void setWidth(int W)
	{
		mWidth = W;
	}
	// 获取
	int getWidth()
	{
		return mWidth;
	}
	// 设置
	void setHeight(int Height)
	{
		mHeight = Height;
	}
	// 获取
	int getHeight()
	{
		return mHeight;
	}
	// 求面积
	int getArea()
	{
		return 2 * (mHeight*mWidth + mHeight * mLength + mWidth * mLength);
	}
	// 求体积
	int getVolume()
	{
		return mLength * mWidth*mHeight;
	}

	// 类成员比较两个正方形是否相等
	bool compare(Cube &ob)
	{
		// 类内可以直接访问成员变量
		if (mLength == ob.mLength 
			&& mWidth == ob.mWidth
			&& mHeight == ob.mHeight)
			return true;
		return false;
	}
};

// 全局函数比较两个正方形是否相等
bool globalCompare(Cube &ob01, Cube &ob02)
{
	// 类外不可以直接访问成员变量
	//if (ob01.mLength == ob02.mLength && ob01.mWidth == ob02.mWidth	&& ob01.mHeight == ob02.mHeight)

	// 需要通过公共方法获取私有成员变量
	if (ob01.getLength() == ob02.getLength()
		&& ob01.getWidth() == ob02.getWidth()
		&& ob01.getHeight() == ob02.getHeight())
		return true;
	return false;
}

int main()
{
	// 实例化一个对象
	Cube ob01;
	ob01.CubeInit(10, 20, 30);
	ob01.setLength(100);
	ob01.setWidth(200);
	ob01.setHeight(300);

	cout << "面积:" << ob01.getArea() << ", 体积:" << ob01.getVolume() << endl;

	Cube ob02;
	ob02.CubeInit(100, 200, 300);
	cout << "全局函数比较" << endl;
	if (globalCompare(ob01, ob02))
		cout << "ob01 和 ob02 相等" << endl;
	else
		cout << "ob01 和 ob02 不相等" << endl;
	cout << "类成员函数比较" << endl;
	if (ob01.compare(ob02))
		cout << "ob01 和 ob02 相等" << endl;
	else
		cout << "ob01 和 ob02 不相等" << endl;

	return 0;
}

输出:

面积:220000, 体积:6000000
全局函数比较
ob01 和 ob02 相等
类成员函数比较
ob01 和 ob02 相等

四、成员函数在类外实现

成员函数在类内实现,会显得非常的冗重。C++支持成员函数在类中声明,类外实现;需要注意的是,类外实现成员函数一定要加作用域,否则就是一个普通的全局函数。
格式:

返回值类型 类名::成员函数(参数列表)
{
	// 函数实现
}

比如把上面实现的Persion的成员函数放到类外面:

#include <iostream>
using namespace std;
#define STR_LEN		32
class Person {
	// 类中默认私有
private:
	// 成员变量和成员函数
	char mName[STR_LEN];//不要给类成员初始化
	int mAge;

public:
	// 在类的内部声明
	void PersonInit(const char *name,int age);
	void setName(const char* name);
	char *getName();
	void setAge(int age);
	int getAge();
	void show();
	
};

// 类外部实现,需要加作用域
void Person::PersonInit(const char *name,int age)
{
	if (name == NULL)
		cout << "名字不能为空" << endl;
	else
		strncpy(mName, name, STR_LEN);
	if (age > 0 && age <= 100)
		mAge = age;
	else
		cout << "输入的age:" << age << "不合法" << endl;

}
// 设置mName
void Person::setName(const char* name)
{
	if (name == NULL)
		cout << "名字不能为空" << endl;
	else
		strncpy(mName, name, STR_LEN);
}
// 获取mName
char* Person::getName()
{
	return mName;
}
// 设置mAge
void Person::setAge(int age)
{
	if (age > 0 && age <= 100)
		mAge = age;
	else
		cout << "输入的age:" << age << "不合法" << endl;
}
// 获取mAge
int Person::getAge()
{
	return mAge;
}
// 显示mName和mAge
void Person::show()
{
	cout << "名字:" << mName << ",年龄:" << mAge << endl;
}


int main()
{
	// 实例化一个对象
	Person obj;
	obj.PersonInit("Long",20);
	obj.setName("Lion");
	obj.setAge(18);
	cout << "名字:" << obj.getName() << ",年龄:" << obj.getAge() << endl;
	
	obj.show();
	return 0;
}

五、类在其他源文件中实现

在头文件里定义类,然后在源文件里实现类的成员函数。

比如把上面实现的Persion的成员函数放到不同文件中。

Person.h

#ifndef _PERSON_H_
#define  _PERSON_H_
#include <iostream>
using namespace std;
#define STR_LEN		32
class Person {
	// 类中默认私有
private:
	// 成员变量和成员函数
	char mName[STR_LEN];//不要给类成员初始化
	int mAge;

public:
	// 在类的内部声明
	void PersonInit(const char *name,int age);
	void setName(const char* name);
	char *getName();
	void setAge(int age);
	int getAge();
	void show();
	
};

#endif

Person.cpp

#include "Person.h"

void Person::PersonInit(const char *name,int age)
{
	if (name == NULL)
		cout << "名字不能为空" << endl;
	else
		strncpy(mName, name, STR_LEN);
	if (age > 0 && age <= 100)
		mAge = age;
	else
		cout << "输入的age:" << age << "不合法" << endl;

}
// 设置mName
void Person::setName(const char* name)
{
	if (name == NULL)
		cout << "名字不能为空" << endl;
	else
		strncpy(mName, name, STR_LEN);
}
// 获取mName
char* Person::getName()
{
	return mName;
}
// 设置mAge
void Person::setAge(int age)
{
	if (age > 0 && age <= 100)
		mAge = age;
	else
		cout << "输入的age:" << age << "不合法" << endl;
}
// 获取mAge
int Person::getAge()
{
	return mAge;
}
// 显示mName和mAge
void Person::show()
{
	cout << "名字:" << mName << ",年龄:" << mAge << endl;
}

main.cpp

#include "Person.h"

int main()
{
	// 实例化一个对象
	Person obj;
	obj.PersonInit("Long",20);
	obj.setName("Lion");
	obj.setAge(18);
	cout << "名字:" << obj.getName() << ",年龄:" << obj.getAge() << endl;
	
	obj.show();
	return 0;
}

这样在使用这个类是只需要包含头文件即可。

六、总结

C++中,类是一种用户自定义的数据类型,它将数据和操作封装在一起。对象是该类的实例化,也就是创建了一个该类类型的变量。

类通常包括以下成员:

  1. 数据成员:用于存储对象状态信息的变量。

  2. 成员函数:用于操作数据成员和完成其他任务的函数。

  3. 构造函数:用于初始化对象的特殊函数。

  4. 析构函数:用于清理对象资源的特殊函数。

  5. 访问控制修饰符:public、private、protected,用于限制对成员的访问权限。

  6. 静态成员变量和静态成员函数:与类相关联而不是与任何单个对象相关联的成员。

使用类时,可以创建多个对象,并且每个对象都具有自己的状态和行为。通过这种方式,可以轻松管理程序中大量复杂数据结构。
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lion Long

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值