在浏览互联网时,我遇到了 这个帖子, ,其中包括这个

“(写得很好)C ++竭尽全力使堆栈自动对象起作用”,就像“原始”一样,如Stroustrup的建议所反映的“像INT一样执行”。这需要更大程度地遵守面向对象的发展原则:您的班级直到遵循“三个规则”(保证它可以(就像int一样)被创建,复制并正确地被销毁为堆栈自动变速箱)的“规则”之后,您的班级不正确。”

我写了一些 C 和 C++ 代码,但只是顺便写了一些,从来没有做过任何严肃的事情,但我只是很好奇,它到底意味着什么?

有人可以举个例子吗?

有帮助吗?

解决方案

堆栈对象由编译器自动处理。

当离开范围时,它被删除。

{
   obj a;
} // a is destroyed here

当您对“新”对象执行相同操作时,您会遇到内存泄漏:

{
    obj* b = new obj;
}

b 没有被销毁,因此我们失去了回收 b 拥有的内存的能力。也许更糟糕的是,该物体无法自行清理。

在 C 语言中,以下内容是常见的:

{
   FILE* pF = fopen( ... );
   // ... do sth with pF
   fclose( pF );
}

在 C++ 中我们这样写:

{
   std::fstream f( ... );
   // do sth with f
} // here f gets auto magically destroyed and the destructor frees the file

当我们忘记在 C 示例中调用 fclose 时,文件不会关闭,并且可能不会被其他程序使用。(例如。无法删除)。

另一个例子,演示了对象字符串,它可以被构造、分配,并在退出作用域时被销毁。

{
   string v( "bob" );
   string k;

   v = k
   // v now contains "bob"
} // v + k are destroyed here, and any memory used by v + k is freed

其他提示

除了其他答案之外:

C++语言实际上有 auto 关键字显式声明对象的存储类。当然,这是完全没有必要的,因为这是局部变量的隐含存储类,不能在任何地方使用。相反的是 autostatic (本地和全球)。

以下两个声明是等效的:

int main() {
    int a;
    auto int b;
}

因为这个关键字完全没用,所以它实际上会在下一个 C++ 标准(“C++0x”)中被回收并获得新的含义,即它让编译器从变量的初始化中推断出变量类型(例如 var 在 C# 中):

auto a = std::max(1.0, 4.0); // `a` now has type double.

C++ 中的变量可以在堆栈或堆上声明。当您在 C++ 中声明变量时,它会自动进入堆栈,除非您显式使用 new 运算符(它进入堆)。

MyObject x = MyObject(params); // onto the stack

MyObject * y = new MyObject(params); // onto the heap

这对内存管理方式产生了很大的影响。当一个变量在堆栈上声明时,当它超出范围时,它将被释放。在对象上显式调用 delete 之前,堆上的变量不会被销毁。

自动堆栈是在当前方法的堆栈上分配的变量。设计一个可以充当堆栈自动功能的类背后的想法是,应该可以通过一次调用完全初始化它,并通过另一次调用销毁它。析构函数必须释放对象分配的所有资源,并且其构造函数返回一个已完全初始化并可供使用的对象,这一点至关重要。类似地,对于复制操作 - 类应该能够轻松地进行复制,其功能齐全且独立。

此类的用法应该类似于原始 int、float 等的用法。被使用。您定义它们(最终给它们一些初始值),然后传递它们,最后让编译器进行清理。

如果我错了,请纠正我,但我认为复制操作对于充分利用自动堆栈清理并不是强制性的。例如,考虑一个经典的 MutexGuard 对象,它不需要复制操作即可作为堆栈自动使用,或者是吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top