其他
啥是封装?来看C++这个小技巧
来源 :今日头条@小智雅汇
将程序中重复出现的代码块提炼成一个函数,也可以理解为一种封装。如果将一个事物相关的数据及对这些数据的处理封装起来,这就是类的概念。
毫无疑问,封装可以实现代码的重用、任务的分治、实现(implementaion)和接口(interfavce)的分离以及提高代码的安全性。
1 封装类更易于使用,并降低程序的复杂性。
封装将对象实现的细节隐藏在对象的用户之外。相反,对象的用户通过公共接口访问对象。这样,用户就可以使用对象,而不必了解它是如何实现的。简单说,类由设计者完成实现,而类的使用者只需了解接口即可拿过来使用(实现和接口的分离)。正因为如此,我们才可以在编程语言中使用函数库或类库,而不是每一个程序都要从0开始。
对于完全封装的类,您只需要知道哪些成员函数可以公开使用该类,它们采用什么参数,以及返回什么值。类是如何在内部实现的并不重要。例如,包含一系列名字的类可以使用C风格字符串的动态数组、std::vector、std::map、std::list或许多其他数据结构中的一个来实现。为了使用这个类,您不需要知道(或关心)某个是如何实现的。这大大降低了程序的复杂性,也减少了错误。这比任何其他原因都重要,这是封装的关键优势。
2 封装类有助于保护数据并防止误用
Global variables are dangerous because you don’t have strict control over who has access to the global variable, or how they use it. Classes with public members suffer from the same problem, just on a smaller scale.
全局变量是危险的,因为您无法严格控制谁可以访问全局变量,或如何使用全局变量。有公共成员的类也有同样的问题,只是规模较小。
例如,假设我们正在编写一个字符串类。我们可以这样开始:
class MyString
{
char *m_string; // we'll dynamically allocate our string here
int m_length; // we need to keep track of the string length
};
我们还可以帮助保护用户避免在使用我们的类时出错。考虑一个具有公共数组成员变量的类:
class IntArray
{
public:
int m_array[10];
};
int main()
{
IntArray array;
array.m_array[16] = 2; // invalid array index, now we overwrote memory that we don't own
}
class IntArray
{
private:
int m_array[10]; // user can not access this directly any more
public:
void setValue(int index, int value)
{
// If the index is invalid, do nothing
if (index < 0 || index >= 10)
return;
m_array[index] = value;
}
};
3 封装类更易于更改
举个简单的例子:
#include <iostream>
class Something
{
public:
int m_value1;
int m_value2;
int m_value3;
};
int main()
{
Something something;
something.m_value1 = 5;
std::cout << something.m_value1 << '\n';
}
#include <iostream>
class Something
{
private:
int m_value1;
int m_value2;
int m_value3;
public:
void setValue1(int value) { m_value1 = value; }
int getValue1() { return m_value1; }
};
int main()
{
Something something;
something.setValue1(5);
std::cout << something.getValue1() << '\n';
}
#include <iostream>
class Something
{
private:
int m_value[3]; // note: we changed the implementation of this class!
public:
// We have to update any member functions to reflect the new implementation
void setValue1(int value) { m_value[0] = value; }
int getValue1() { return m_value[0]; }
};
int main()
{
// But our program still works just fine!
Something something;
something.setValue1(5);
std::cout << something.getValue1() << '\n';
}
4 封装类更易于调试
最后,封装有助于在出现问题时调试程序。通常当程序不能正常工作时,是因为我们的一个成员变量的值不正确。如果每个人都可以直接访问该变量,那么跟踪修改该变量的代码片段可能会很困难(可能是其中的任何一个,您需要对它们进行断点操作才能确定是哪一个)。但是,如果每个人都必须调用同一个公共函数来修改一个值,那么您可以简单地中断该函数并观察每个调用方更改该值,直到您看到它出错的地方。
-END-
推荐阅读
【01】每个工程师都应该了解的一些 C++ 特性【02】C++中是如何实现智能指针的?【03】C++ 救不了程序员!【04】现在市场上,C++ 主要用来做什么?【05】C++虚函数的深入理解