避免使用指针时 C++ 中的性能和安全性
Performance and security in C++ when avoiding use of pointer
我正在尝试用 C++ 创建一个 class 以实现绝对封装和效率的想法,以便于实践。在我的例子中,这意味着每个数据成员都应该在 class 内部,没有指向外部的指针(例如动态分配的存储)。
例如,我正在使用
char name [10];
而不是
std::string name;
char* name;
我的想法是 class 的对象在堆栈上创建为 完全封闭的块 。以及性能的提高,因为,如果我没记错的话,访问堆栈比访问堆快得多。
我的这些假设是否正确?
并且这种绝对封装的想法在实践之外是否合理?(例如确保安全,因为似乎没有内存管理不善或缓冲区溢出的风险)
access to the stack is considerably faster than to the heap
这是错误的:对内存的访问就是对内存的访问。有两件事可能让您感到困惑。
首先,确实可以以不同的速度访问不同类型的内存。例如,磁盘通常是最慢的(不谈网络,这会使事情变得更加复杂),而寄存器通常是最快的。两者之间是主内存或 RAM,堆栈和堆都存在于其中。然后你可以有缓存,不同类型的磁盘等等。
其次,栈分配确实比堆分配快,只是因为分配方案更简单。使用堆栈,顾名思义,您只能在最后分配和释放,这意味着您需要遵循特定的顺序。使用堆,您几乎可以在任何地方进行分配,这意味着您可以在任何时间以任何顺序取消分配。这意味着对内存的某种管理会带来自身的问题,例如碎片。
is this idea of absolute encapsulation sensible outside practice?
首先,仅使用堆栈在实践中是不可能的,因为它的大小有限。虽然这个大小在实践中可能会有所不同,但目前不太可能超过 8MB。一旦你需要加载一个更大的文件,你就不能在堆栈上完成。
然而,即使栈大小实际上是无限的,你仍然需要按照你分配它们的相反顺序释放东西,否则它不再是一个栈。那样做很多事情是行不通的。例如,一旦需要交互性,就需要某种事件处理(以响应用户输入),而这通常使用队列来完成,队列与堆栈相反。当然你可以分配一个非常大的队列,但在实践中这是不可行的。我想到的另一个例子是网络。如果您想一次处理多个连接(例如网络浏览器),则需要独立处理与每个连接关联的内存。同样,您可以为每个连接分配大量内存,但同样,这在实践中是不可行的。
另外,请注意封装并不意味着"no pointers to dynamically allocated memory"。相反,"hidden memory management"会更接近这个概念的意思。
我正在尝试用 C++ 创建一个 class 以实现绝对封装和效率的想法,以便于实践。在我的例子中,这意味着每个数据成员都应该在 class 内部,没有指向外部的指针(例如动态分配的存储)。
例如,我正在使用
char name [10];
而不是
std::string name;
char* name;
我的想法是 class 的对象在堆栈上创建为 完全封闭的块 。以及性能的提高,因为,如果我没记错的话,访问堆栈比访问堆快得多。
我的这些假设是否正确?
并且这种绝对封装的想法在实践之外是否合理?(例如确保安全,因为似乎没有内存管理不善或缓冲区溢出的风险)
access to the stack is considerably faster than to the heap
这是错误的:对内存的访问就是对内存的访问。有两件事可能让您感到困惑。
首先,确实可以以不同的速度访问不同类型的内存。例如,磁盘通常是最慢的(不谈网络,这会使事情变得更加复杂),而寄存器通常是最快的。两者之间是主内存或 RAM,堆栈和堆都存在于其中。然后你可以有缓存,不同类型的磁盘等等。
其次,栈分配确实比堆分配快,只是因为分配方案更简单。使用堆栈,顾名思义,您只能在最后分配和释放,这意味着您需要遵循特定的顺序。使用堆,您几乎可以在任何地方进行分配,这意味着您可以在任何时间以任何顺序取消分配。这意味着对内存的某种管理会带来自身的问题,例如碎片。
is this idea of absolute encapsulation sensible outside practice?
首先,仅使用堆栈在实践中是不可能的,因为它的大小有限。虽然这个大小在实践中可能会有所不同,但目前不太可能超过 8MB。一旦你需要加载一个更大的文件,你就不能在堆栈上完成。
然而,即使栈大小实际上是无限的,你仍然需要按照你分配它们的相反顺序释放东西,否则它不再是一个栈。那样做很多事情是行不通的。例如,一旦需要交互性,就需要某种事件处理(以响应用户输入),而这通常使用队列来完成,队列与堆栈相反。当然你可以分配一个非常大的队列,但在实践中这是不可行的。我想到的另一个例子是网络。如果您想一次处理多个连接(例如网络浏览器),则需要独立处理与每个连接关联的内存。同样,您可以为每个连接分配大量内存,但同样,这在实践中是不可行的。
另外,请注意封装并不意味着"no pointers to dynamically allocated memory"。相反,"hidden memory management"会更接近这个概念的意思。