“ 本文深入浅出地介绍了 C++ 类,从封装性、定义、设计到实现,循序渐进地讲解了 C++ 类在面向对象编程中的重要作用。阐述了类封装性的概念、语法和格式。展示了如何设计一个类。介绍了类成员函数在类内和类外实现的方法,以及如何在多文件中实现类。”
01
类的封装性
C++中的类封装性是指将数据和操作封装在一个单独的实体(类)中,防止外部代码直接访问对象的数据。类中的成员变量可以被声明为私有(private),以便只能通过类内部的函数来访问它们。
封装提供了以下优点:
1 数据隐藏:类的使用者无法直接访问私有成员变量,从而保护了数据。
2 可控制性:只公开必要的函数接口,可以减少不正确使用或更改数据造成的风险。
3 简化编程:由于用户不能直接更改数据,因此可以简化编写复杂程序时需要处理大量状态信息的过程。
4 提高安全性:由于私有成员变量无法直接访问,因此可以提高程序的安全性并避免未经授权对重要数据进行修改或破坏。
类将具有共性的数据和方法封装在一起,加以权限区分,用户只能通过公共方法访问私有数据。
类的权限分为:
• private:私有。
• protected:保护。
• public:公共。
在类的外部,只有public修饰的成员才能访问,在没有涉及继承与派生时,private和protected是同等级别的,外部不允许访问。用户在类的外部可以通过public的方法间接访问private和protected数据。
访问属性 | |||
属性对象内部对象外部public | |||
公共可以访问可以访问protected | |||
保护可以访问不可访问private |
私有可以访问不可访问02
定义一个类
定义类的时候系统不会为其开辟内存空间,只有当在类的外部实例化一个对象才会为其开辟空间;所以不要给类中的成员初始化。在类的内部不存在权限之分,只有在类外部才涉及权限划分,在定义类时如果没有指定权限修饰符则默认是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;
}
03
设计一个类
设计一个类的步骤:
1 思考类有哪些数据成员。
2 操作这些数据的成员函数有哪些。
3 数据设为私有,成员函数设置为共有。
3.1、示例一:设计一个Person类
比如 设计一个person类,具有name和age属性,提供初始化函数、对name读写的函数以及对age读写的函数;但是需要确保age的赋值有效范围是(0~100),超出有效范围则拒绝赋值,并提供方法输出name和age。
#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×𝑎×𝑏+2×𝑎×𝑐+2×𝑏×𝑐。
• 立方体的体积:𝑎×𝑏×𝑐。
#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 相等
04
成员函数在类外的实现
成员函数在类内实现,会显得非常的冗重。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;
}
05
类在其他源文件中实现
在头文件里定义类,然后在源文件里实现类的成员函数。
比如把上面实现的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;
}
这样在使用这个类是只需要包含头文件即可。
06
总结
C++中,类是一种用户自定义的数据类型,它将数据和操作封装在一起。对象是该类的实例化,也就是创建了一个该类类型的变量。
类通常包括以下成员:
1 数据成员:用于存储对象状态信息的变量。
2 成员函数:用于操作数据成员和完成其他任务的函数。
3 构造函数:用于初始化对象的特殊函数。
4 析构函数:用于清理对象资源的特殊函数。
5 访问控制修饰符:public、private、protected,用于限制对成员的访问权限。
6 静态成员变量和静态成员函数:与类相关联而不是与任何单个对象相关联的成员。
使用类时,可以创建多个对象,并且每个对象都具有自己的状态和行为。通过这种方式,可以轻松管理程序中大量复杂数据结构。