C++面向对象基础:封装原理、访问权限与class/struct差异解析
在C++面向对象编程中,封装不仅将属性与行为聚合于类中,更通过访问权限控制数据的可见性。本文详解public、protected、private的作用域差异,剖析class与struct默认权限的根本不同,并提供属性私有化后的数据验证与对象操作实例。
封装的核心意义
封装是C++面向对象的三大支柱之一,其核心价值在于:
- 结构化设计:将描述事物特征的属性(成员变量)与处理事物的行为(成员函数)封装在一起,使代码逻辑更加内聚。
- 访问控制:通过设定不同的访问权限,限制外部对内部数据的直接访问,从而保护数据安全并防止非法修改。
第1步:定义类的基本语法
目的:创建一个基础的类结构,展示属性与行为的结合。
入口:使用 class 关键字定义类名。
动作:在类体内声明成员变量和成员函数,并使用访问修饰符限定权限。
#include <iostream>
using namespace std;
class Triangle {
public: // 公共权限:类内外均可访问
int m_a; // 直角边a
int m_b; // 直角边b
// 行为:计算面积
double calculate() {
return (m_a * m_b) / 2.0;
}
};
int main() {
Triangle t;
t.m_a = 10;
t.m_b = 10;
cout << "三角形面积:" << t.calculate() << endl;
return 0;
}
第2步:引入私有权限以控制数据访问
目的:防止外部直接修改关键数据,强制通过接口访问。
入口:将属性标记为 private,提供 public 的 setter/getter 方法。
动作:在类外创建对象,调用成员函数而非直接赋值属性。
class Student {
public:
void setName(string name) { m_name = name; }
void setID(int id) { m_id = id; }
void showStudent() {
cout << "Name: " << m_name << " ID: " << m_id << endl;
}
private: // 私有权限:类外无法直接访问
string m_name;
int m_id;
};
int main() {
Student stu;
stu.setName("张三");
stu.setID(101);
stu.showStudent();
// stu.m_name = "李四"; // 编译错误,私有成员不可直接访问
return 0;
}
访问权限详解
C++ 提供了三种访问权限,决定了类成员在类内、类外以及继承关系中的可见性:
public(公共):类内可访问,类外可访问,子类可继承访问。protected(保护):类内可访问,类外不可访问,但子类可以继承访问。private(私有):类内可访问,类外不可访问,子类不可继承访问。
第3步:实践多权限混合应用
目的:理解不同权限在实际编码中的作用范围。 入口:在类中混合使用三种权限修饰符。 动作:在类外尝试访问不同权限的成员,观察编译器报错;在类内成员函数中访问所有权限成员。
class Person {
public:
string m_Name; // 公共权限
protected:
string m_Phone; // 保护权限
private:
int m_Password; // 私有权限
public:
void display() { // 公有成员函数
m_Name = "张三"; // 类内允许
m_Phone = "138..."; // 类内允许
m_Password = 12345; // 类内允许
}
};
int main() {
Person p;
p.m_Name = "李四"; // 正确,public可访问
// p.m_Phone = "..."; // 错误,protected类外不可访问
// p.m_Password = 1; // 错误,private类外不可访问
p.display(); // 正确,调用公有方法间接设置
return 0;
}
注:上述示例中,display 方法仅在类内声明并在类外定义时需加 Person::,此处为了简洁直接在类内实现。实际开发中,若需保持类接口整洁,常将实现移至类外。
class 与 struct 的关键区别
在 C++ 中,class 和 struct 功能几乎完全相同,**唯一的区别在于默认的访问权限**:
class:默认成员(未指定权限时)为private。struct:默认成员(未指定权限时)为public。
第4步:对比默认权限的影响
目的:验证默认访问权限对对象初始化的影响。 动作:分别定义 class 和 struct,不显式指定权限,尝试在 main 中直接赋值成员变量。
class C1 {
int m_A; // 默认为 private
};
struct C2 {
int m_B; // 默认为 public
};
int main() {
C1 c1;
// c1.m_A = 10; // 错误!默认私有帮助
C2 c2;
c2.m_B = 10; // 正确!默认公共
return 0;
}
成员属性私有化的优势与实践
将所有成员属性设置为 private 是封装的最佳实践,主要带来两个优势:
- 权限控制:自定义属性的读写规则(如只读、只写或读写)。
- 数据合法性校验:在 Setter 方法中加入逻辑判断,确保输入数据的有效性。
第5步:实现属性读写控制与校验
目的:通过私有属性配合公有接口,实现健壮的数据管理。 动作:为年龄添加范围检查,为姓名提供全读写,为亲密关系设置仅写入。
class Person {
public:
// 可读可写
void setName(string name) { m_Name = name; }
string getName() { return m_Name; }
// 只读(提供getter,不提供setter,或提供带校验的setter)
int getAge() { return m_Age; }
void setAge(int age) {
if (age < 0 || age > 150) {
cout << "无效的年龄!" << endl;
return;
}
m_Age = age;
}
// 只写(只有setter,没有getter)
void setLover(string lover) { m_Lover = lover; }
private:
string m_Name; // 可读可写
int m_Age; // 只读
string m_Lover; // 只写
};
int main() {
Person p;
p.setName("张三");
cout << "姓名:" << p.getName() << endl;
p.setAge(25); // 合法
p.setAge(-5); // 触发校验失败
p.setLover("阿尼亚");
// cout << p.m_Lover; // 错误,无公开读取接口
return 0;
}
综合案例:立方体对象的封装与比较
本案例利用类知识,将立方体的长宽高设为私有,并提供两种方式比较两个立方体是否相等:全局函数法和成员方法法。
第6步:构建带私有属性的立方体类
目的:练习成员函数的声明与定义,以及私有成员的间接访问。
class Cube {
public:
void setL(int l) { m_L = l; }
int getL() { return m_L; }
void setW(int w) { m_W = w; }
int getW() { return m_W; }
void setH(int h) { m_H = h; }
int getH() { return m_H; }
// 成员方法:比较当前对象与另一个对象
bool isSameByClass(Cube& c) {
return (this->getL() == c.getL() &&
this->getW() == c.getW() &&
this->getH() == c.getH());
}
private:
int m_L, m_W, m_H;
};
// 全局函数:比较两个立方体
// 注意:全局函数无法直接访问私有成员,必须通过getter
bool isSameByGlobalFunc(Cube& c1, Cube& c2) {
return (c1.getL() == c2.getL() &&
c1.getW() == c2.getW() &&
c1.getH() == c2.getH());
}
int main() {
Cube c1, c2;
c1.setL(10); c1.setW(10); c1.setH(10);
c2.setL(10); c2.setW(10); c2.setH(10);
if (c1.isSameByClass(c2)) {
cout << "两立方体相等(成员方法)" << endl;
}
if (isSameByGlobalFunc(c1, c2)) {
cout << "两立方体相等(全局函数)" << endl;
}
return 0;
}
该案例展示了如何通过 getter 方法在类外访问私有数据,体现了封装带来的安全性与控制力。以上就是 C++ 类和对象封装及 class 与 struct 区别的详细内容,更多关于 C++ 面向对象基础知识的学习资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













