为了避免继续使用->
并直接使用对象,是否可以接受以下做法:
obj x = *(new obj(...));
...
delete &obj;
为了避免继续使用->
并直接使用对象,是否可以接受以下做法:
obj x = *(new obj(...));
...
delete &obj;
这不仅是糟糕的做法,而且:
obj
将存储由表达式创建的原始对象的副本new
,并且返回的指向该对象的指针new
丢失;delete
一个指向未分配的对象的指针new
。根据 C++11 标准的第 5.3.5/2 段:[...] 在第一种选择(删除对象)中,delete 的操作数的值可以是空指针值、指向由先前的new-expression创建的非数组对象的指针或指向子对象的指针(1.8) 表示此类对象的基类(第 10 条)。如果不是,则行为未定义。
不,事实上这会导致泄漏。x
是复制初始化的,所以指向的原始对象new obj
丢失了。
只需使用
obj x(...);
无需动态分配。或者
obj x = obj(...);
如果你必须(怀疑)。
当然不是;将动态对象复制到自动变量,丢失指向它的唯一指针,然后尝试删除自动副本。您有内存泄漏和无效删除。
首先使用自动变量会更好:
obj x(...);
...
// no need to delete anything
或者,如果由于某种原因它确实必须是动态的(因为它对于堆栈来说太大了,或者你并不总是想在这里销毁它),然后使用智能指针,如果你真的不喜欢,请使用引用->
std::unique_ptr<obj> p(new obj(...));
obj & x = *p;
...
// still no need to delete anything
将您的更改x
为引用将是有效的(只要您注意异常、早期函数返回等不会导致泄漏),但会在不幸不得不维护它的任何人之间引起混乱。
如果您这样做,您将无法正确删除您的对象。
隐式地执行以下操作。
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A v(*p);
//...
delete &v; // &v != p and v is not constructed via new!
return 0;
}
如果您想使用类似对象的语法,您可以绑定对该对象的引用。
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A & r = *p;
int i = r.test();
delete p;
return 0;
}
如果你通过同一个指针删除你的对象,就不会有泄漏。