在构造动态对象时解引用

dereferencing when constructing dynamic object

本文关键字:引用 对象 动态      更新时间:2023-10-16

为什么不使用以下语句:

struct Foo
{
    int x;
};
int main()
{
    Foo &foo = *new Foo();
    foo.x = 7;
    std::cout << foo.x << std::endl;
    delete &foo;
}
毕竟,必须在可能的情况下使用引用,并且使用这种方法,一旦初始解引用,就不必担心再次忘记它。缺点是什么?编辑:

我知道operator ->,我说的忘记是指

int &n = *new int;
n = 7;
int *m = new int;
*m = 7; //here you can forget it

您将有内存泄漏。您必须在函数末尾做这样的操作:

delete &foo;

可以与智能指针结合使用。

std::unique_ptr<Foo> p(new Foo);
Foo &foo = *p;
//...

然后,内存将在作用域结束时为您正确删除。

这种方法没有明显的缺点。但是,如果必须使用动态分配的引用,即T& t = *new T;,则应该重新考虑设计。
为什么?因为,

"引用必须在声明时初始化。"

这意味着,你不能做T& t;,然后分配一些内存给它。
下面的语句:

T& t = *new T;  // (1) costly heap allocation (2) exception handling (3) need cleaning

成为了

的低级替代品
T t;  // (1) cheaper auto allocation (2) no exception (2) no need to clean

所以即使你可以动态分配引用,它们也几乎不需要。

回复:"必须尽可能使用引用"?这个(坏)建议是从哪里来的?

Foo foo;
foo.x = 7;
std::cout << foo.x << std::endl;

没有指针,没有引用,没有自由存储,没有delete

但是当你从自由存储区分配时,你会得到一个指向数据对象的指针。不要把它变成引用,除非你绝对有必要,即使这样,也不要这样做。