4

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

“(写得很好)C++ 竭尽全力使堆栈自动对象“像”原语一样工作,这反映在 Stroustrup 的“像整数一样做”的建议中。这需要更加遵守面向对象开发的原则:你的类是不正确的,直到它“像”一个 int 一样工作,遵循“三法则”,保证它可以(就像一个 int 一样)作为堆栈自动被创建、复制和正确销毁。

我已经编写了一些 C 和 C++ 代码,但只是顺便说一句,从来没有什么严重的事情,但我只是好奇,这到底是什么意思?

有人可以举个例子吗?

4

5 回答 5

12

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

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

{
   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
于 2008-08-27T13:59:22.387 回答
2

除了其他答案:

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.
于 2008-08-27T14:15:57.243 回答
1

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

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

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

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

于 2008-08-27T13:37:36.307 回答
1

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

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

于 2008-08-27T13:42:05.780 回答
1

Correct me if i'm wrong, but i think that copy operation is not mandatory to take full advantage of automatic stack cleaning. For example consider a classic MutexGuard object, it doesn't need a copy operation to be useful as stack automatic, or does it ?

于 2010-12-01T22:45:03.273 回答