-2

多年来我一直在使用 Java。现在我需要了解一段 C++ 程序。

TimeStamp theTimeStamp;
theTimeStamp.update();

令我困惑的是为什么我们不写

TimeStamp theTimeStamp = new(); 

我的直觉是,要使用一个对象,首先应该分配一个内存空间并与该对象关联。

我想这是 Java 和 C++ 根本不同的地方?你能澄清一下吗?

[EDIED] 我写了'TimeStamp theTimeStamp = malloc();'

4

4 回答 4

6

你永远不会用TimeStamp theTimeStamp = malloc();C++ 编写。

首先,因为malloc它来自 C 并且真的不应该在 C++ 中使用。其次,它不知道它的上下文,需要一个参数来指定它必须分配多少内存,并返回一个你需要转换的无类型指针。

相反,你会写

TimeStamp * theTimeStamp = new TimeStamp();

看 - 这与 Java 非常相似。注意到里面了*吗?那是为了指定 thattheTimeStamp是一个指针(在 Java 中,用户定义类型的每个变量都是一个指针/引用,因此您不必关心明确说明这一点)。

但是,在 C++ 中,您可以选择是否要

  • C++ 使用变量范围自动处理创建和销毁(即,没有*, 就像在您的第一个代码示例中所做的那样)。然而,这意味着一旦theTimeStamp超出范围(即通常在定义变量的块的末尾),变量将自动销毁。
  • 或者,如果您想自己进行动态内存分配(Java 中的默认情况) - 但与 Java 相比,您还必须自己关心在 C++ 中删除对象。

必须“手动”处理删除是为什么在 C++ 中通常不直接使用这种原始指针,而是使用所谓的智能指针类型,例如std::shared_ptr来自新的 C++11 标准。它们使您不必手动进行删除(并且在许多情况下可能会忘记它)。还有其他智能指针类型;然而,shared_ptr它提供了与 Java 所做的最相似的事情 - 您可以将 a 分配shared_ptr给另一个,从而保持它指向的对象处于活动状态,并且只有当指向对象的最后一个共享指针被销毁时,指向的对象也会是被摧毁。

然而,只要有可能,在 C++ 中最好完全避免使用指针,而是使用自动分配的变量。

于 2013-10-30T08:45:20.690 回答
3

这样想。在java中,当你想要一个int时,你不这样做

int i = new int(5);
i++;

你做

int i = 5;
i++;

在 Java 中,原语和对象是有区别的。原语在没有 new 的情况下在堆栈上分配,并在作用域结束时被销毁。对象被分配新的并被垃圾收集。

在 C++ 中,您编写的每个类默认情况下都像一个原语。它在堆栈上创建,并在范围结束时被销毁。您可以通过编写构造函数和析构函数来控制创建和销毁时发生的事情。现在,只要您的变量受范围限制,它就可以很好地工作。如果不是这种情况,您可以使用 new(旧样式)或 make_unique/make_shared(现代样式)在堆上分配类的对象。

于 2013-10-30T13:12:43.377 回答
2

在您给出的示例中,由于没有传递任何参数,因此调用 TimeStamp 的构造函数而不使用任何参数来在堆栈上创建一个新的 TimeStamp。此变量将在其范围用完时被删除(使用新的堆栈帧)。

malloc分配作为参数传递的一定数量的内存,并将 void* 返回到该大小的块。这块内存是在堆上分配的,作用域用完时不会被删除,必须free显式d。

但是,鉴于这是 C++,您不想使用mallocand free,您应该坚持使用友好的 C++ 变体 new 和 delete。

于 2013-10-30T08:42:01.683 回答
2

自动变量是在程序流进入和离开变量的上下文时自动分配和释放的变量。

默认情况下,在代码块中声明的所有变量都是自动的。

所以当流量达到

TimeStamp theTimeStamp;

它使用默认构造函数自动在堆栈上分配此对象。当流到达时,析构函数也会自动调用}

您还可以使用动态内存分配它:

TimeStamp *theTimeStamp = new TimeStamp(); //calling default constructor

delete theTimeStamp;手动。

永远不要使用 malloc 或 free 来分配类变量(对象)。

于 2013-10-30T08:47:58.910 回答