C ++ - “Stack automatic”是什么意思?

时间:2008-08-27 13:31:22

标签: c++ oop

在我的互联网浏览中,我遇到了this post,其中包含了这个

  

“(写得好)C ++很棒   长度使堆栈自动化   对象工作“就像”原语,   正如Stroustrup建议的那样   “像投注那样做”。这需要一个   更加坚持   面向对象的原则   发展:你的班级不对   直到它“像”一个int,   遵循“三法则”即   保证它可以(就像一个int)   被创建,复制和正确   被自动摧毁。“

我已经完成了一些C和C ++代码,但只是顺便说一下,从来没有任何严肃的事情,但我只是好奇,这究竟意味着什么?

有人能举个例子吗?

5 个答案:

答案 0 :(得分:12)

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

当保留范围时,它将被删除。

{
   obj a;
} // a is destroyed here

对“newed”对象执行相同操作时会出现内存泄漏:

{
    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

答案 1 :(得分:2)

除了其他答案:

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

以下两个声明是等效的:

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

因为关键字完全无用,它实际上会在下一个C ++标准(“C ++ 0x”)中被回收并获得一个新含义,即它允许编译器从其初始化中推断出变量类型(如{在C#中{1}}:

var

答案 2 :(得分:1)

C ++中的变量既可以在堆栈上声明,也可以在堆上声明。当你在C ++中声明一个变量时,它会自动进入堆栈,除非你明确地使用new运算符(它进入堆)。

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

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

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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