首页 > 解决方案 > 避免使用指针时 C++ 中的性能和安全性

问题描述

为了实践,我正在尝试用绝对封装和效率的想法在 C++ 中创建一个类。在我的情况下,这意味着每个数据成员都应该在类内部,没有指向外部的指针(例如,动态分配的存储)。

例如,我正在使用

char name [10];

代替

std::string name;
char* name;

我的想法是类的对象被创建为堆栈上完全封闭的块。除了提高性能外,如果我没记错的话,访问堆栈比访问堆要快得多。

我在这些假设中正确吗?

这种绝对封装的想法在实践之外是否合理?(例如为了确保安全,因为似乎没有内存管理不善或缓冲区溢出的风险)

标签: c++performancesecuritystackencapsulation

解决方案


访问堆栈比访问堆快得多

这是错误的:对内存的访问就是对内存的访问。这里有两件事可能让你感到困惑。

首先,确实可以以不同的速度访问不同类型的内存。例如,磁盘通常是最慢的(不谈网络,这会使事情更加复杂),而寄存器通常是最快的。介于两者之间的是主内存或 RAM,堆栈和堆都在其中。然后你可以拥有缓存、不同类型的磁盘等等。

其次,栈分配确实比堆分配快,只是因为分配方案更简单。使用堆栈,顾名思义,您只能在最后分配和释放,这意味着您需要遵循特定的顺序。使用堆,您几乎可以在任何地方进行分配,这意味着您可以在任何时候以任何顺序解除分配。这意味着对内存进行某种管理,它本身就有问题,例如碎片。

这种绝对封装的想法在实践之外是否合理?

首先,仅仅使用堆栈是不可能的,因为它的大小有限。虽然这个大小在实践中可能会有所不同,但目前不太可能超过 8MB。一旦您需要加载大于该文件的文件,您就无法在堆栈上执行此操作。

但是,即使堆栈大小实际上是无限的,您仍然需要按照分配它们的相反顺序释放它们,否则它不再是一个堆栈。很多事情都是这样行不通的。例如,一旦你想要交互,你就需要某种事件处理(响应用户输入),这通常是通过队列来完成的,这就像堆栈的反面一样。当然,您可以分配一个非常大的队列,但这在实践中是不可行的。我想到的另一个例子是网络。如果您想一次处理多个连接(例如 Web 浏览器),您需要独立处理与每个连接关联的内存。同样,您可以为每个连接分配大量内存,但同样,这在实践中是不可行的。

另外,请注意,封装并不意味着“没有指向动态分配内存的指针”。相反,“隐藏的内存管理”会更接近这个概念的含义。


推荐阅读