A *a = new A(); 这行代码创建一个指针还是一个对象?

21
A *a = new A();

这会创建一个指针还是对象?

我是一名C++初学者,所以我想了解这个区别。


10
如果只创建了一个指针,那么这个指针会指向什么呢? - Mat
49
当您购买一所新房时,您获得的是新的街道地址还是新的房子? - user541686
2
指针本身也是一个对象。 - Nawaz
2
A *a 是一个指针。它可以保存一个地址。new A() 返回一个新创建对象的地址。 - Hot Licks
7个回答

44

你创建了一个 A 的新实例(即对象),并创建了一个指向该实例的指针称为 a

你可以将其分为两个语句:

A *a;        // Declare `a` of type: pointer to `A`

a = new A(); // create a new instance of `A` and
             // assign the resulting pointer to `a`

15
这会在堆上创建一个类型为A的对象,并将指针存储在a中(该指针存储在堆栈中)。
P.S.别忘了在使用完后调用delete a,以便销毁A并将其内存归还给堆。最好将a转换为智能指针。

希望您不介意微小的编辑,以澄清变量 a 存储的位置。 - Ed Heal
如果A类的构造函数不是异常安全的,那么可能会抛出异常并且不会创建实例,在这种情况下调用delete将导致运行时错误。 - spin_eight
7
更准确地说,不要担心安全删除,而是记得使用智能指针。 - chris
1
@spin_eight - 将指针初始化为0;如果 A 的构造函数引发异常,则 delete a 仍然可以正常工作。不需要智能指针或检查任何内容。 - Pete Becker
@ Pete Becker 实际上我的意思是,这个答案可以包含更详细的信息,它并没有涵盖所有可能的变体,要覆盖它们需要提供大量的信息。我认为,在给出相对简短的答案时,为主题发起者提供初学者书籍/网站的参考资料会很好。另外要补充的是,操作符new可以被重载,因此在这种情况下,不能保证类的实例将被创建。 - spin_eight
@spin_eight:如果您认为一个答案需要更多的细节(我不这么认为),我认为最有建设性的方法是自己写一个。 - NPE

11

它同时创建两者。


它在栈上创建类型为A*的对象,并在堆上创建类型为A的对象。

等价于

A *a;
a = new A();

4

这将创建对象和指针。


首先,调用new A(),如果您有默认构造函数,则调用该构造函数并使用默认值初始化该对象,否则将使用默认值进行初始化。因为我们使用了new关键字,所以它会在堆上为对象A分配内存。new关键字用于在堆上动态分配内存。NEW返回对象的起始地址。

之后是A类型的指针,它将具有由new运算符返回的对象A()的地址。


3
正如其他人所说,它会创建两个对象。但是,对象A是在自由存储区中创建的,现在你必须记得手动delete它。请注意,C++中的任何函数都可能抛出异常,除非它声明为noexcept。因此,现在不仅要记住在没有抛出异常时delete,还需要想象代码可能采取的所有路径,并编写适当的try-catch块来手动delete对象。
你正在做的称为裸new,这是一种容易让自己陷入困境的方法。
幸运的是,C++11解决了这个问题:智能指针。考虑指针的语义,它将由一个实体拥有还是在多个实体之间共享?在前一种情况下,您将需要使用std::unique_ptr
#include <memory>

std::unique_ptr<A> a(new A{});

现在你不需要调用delete,内存管理已经为你处理。在后一种情况下,你需要使用std::shared_ptr

#include <memory>

std::shared_ptr<A> a(new A{});

但是C++中关于序列点的定义可能无法保证这种创建智能指针的方式总是安全的,不详细解释:

std::shared_ptr<A>(new A{new B, new C});

可能会产生内存泄漏,为了避免这种情况,使用 std::make_shared

#include <memory>

auto a = std::make_shared<A>(); // a now holds a shared_ptr to A

很遗憾,在完成C++11时,委员会忘记了std::make_unique。这个问题应该在C++14中得到解决:

#include <memory>

auto a = std::make_unique<A>(); // a now holds a unique_ptr to A

1

它会创建两个东西。

首先,您需要创建一个类型为A的对象,然后存储指向它的指针。

有关指针的更多信息,请查看此处


0

对象和指针。对象必须有一个指针供您引用,但是您可以有多个指针指向同一个对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接