C ++-"自动堆栈"是什么意思?
在互联网上浏览时,我遇到了这篇文章,其中包括
"(Well written) C++ goes to great lengths to make stack automatic objects work "just like" primitives, as reflected in Stroustrup's advice to "do as the ints do". This requires a much greater adherence to the principles of Object Oriented development: your class isn't right until it "works like" an int, following the "Rule of Three" that guarantees it can (just like an int) be created, copied, and correctly destroyed as a stack automatic."
我已经做了一些C和C ++代码,但是顺便说一句,从不认真,但是我很好奇,这到底意味着什么?
有人可以举个例子吗?
解决方案
回答
C ++中的变量可以在堆栈或者堆上声明。在C ++中声明变量时,除非我们显式使用new运算符(将其放入堆),否则它将自动进入堆栈。
MyObject x = MyObject(params); // onto the stack MyObject * y = new MyObject(params); // onto the heap
这在内存管理方式上有很大的不同。在堆栈上声明变量时,超出范围时将释放该变量。在对象上显式调用delete之前,不会破坏堆上的变量。
回答
自动堆栈是在当前方法的堆栈上分配的变量。设计一个可以自动执行Stack的类的想法是,应该可以通过一个调用将其完全初始化,而在另一个调用中将其销毁。析构函数必须释放该对象分配的所有资源,并且其构造函数返回已完全初始化并可以使用的对象,这一点至关重要。类似地,对于复制操作,该类应该能够轻松地制作成具有完全功能且独立的副本。
此类的用法应类似于原始int,float等的用法。我们定义它们(最终给它们一些初始值),然后传递它们,最后将编译器交给清理人员。
回答
堆栈对象由编译器自动处理。
保留范围后,将其删除。
{ 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
关键字来显式声明对象的存储类。当然,这完全没有必要,因为这是局部变量的隐含存储类,不能在任何地方使用。 " auto"的相反是" static"(本地和全局)。
以下两个声明是等效的:
int main() { int a; auto int b; }
因为该关键字完全没有用,所以实际上它将在下一个C ++标准(C ++ 0x)中回收并得到新的含义,即,它使编译器从其初始化中推断变量类型(如C#中的var)。 :
auto a = std::max(1.0, 4.0); // `a` now has type double.
回答
如果我错了,请纠正我,但是我认为复制操作不是强制性的,以充分利用自动堆栈清洁功能。
例如,考虑一个经典的MutexGuard对象,它不需要复制操作就可以自动用作堆栈,还是这样?