Java程序员想要理解C ++代码:使用没有new的对象的方法

时间:2013-10-30 08:35:40

标签: c++ malloc new-operator

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

TimeStamp theTimeStamp;
theTimeStamp.update();

让我感到困惑的是我们为什么不写

TimeStamp theTimeStamp = new(); 

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

我想这是Java和C ++从根本上有所不同的一点?你能澄清一下吗?

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

4 个答案:

答案 0 :(得分:6)

你永远不会在C ++中写TimeStamp theTimeStamp = malloc();

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

相反,你需要例如写

TimeStamp * theTimeStamp = new TimeStamp();

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

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

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

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

无论何时你都可以,但在C ++中最好不要使用指针,而是使用自动分配的变量。

答案 1 :(得分:3)

以这种方式考虑这一点。在java中,当你想要一个int时,你不做

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

你做

int i = 5;
i++;

在Java中,基元和对象之间存在区别。基元在没有new的情况下分配在堆栈上,并在范围的末尾被销毁。对象分配有新对象并进行垃圾回收。

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

答案 2 :(得分:2)

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

malloc分配作为参数传递的内存量,并将void *返回给该大小的块。此内存在堆上分配,并且在作用域用完时不会被删除,并且必须明确free

虽然看来这是C ++但是你不想使用mallocfree,你应该坚持使用友好的C ++变体new和delete。

答案 3 :(得分:2)

自动变量是一个变量,当程序流进入并离开变量的上下文时,它会自动分配和解除分配。

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

所以当流程达到

TimeStamp theTimeStamp;

它使用默认构造函数自动在堆栈上分配此对象。当流量达到}

时,也会自动调用析构函数

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

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

手动delete theTimeStamp;

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