如果它有一个对象,让我们调用它o
,typeo *a,*b;
如果我将o
两个数组分配给数组a
和数组,b
那么delete[] b
如果我尝试访问 a 中的 o 或 o 会发生什么?例如:
struct name{int a;}
name *a = new name[1];
name *b = new name[1];
name o;
a[0] = o;
b[0] = o;
delete[] b;
a[0]; // what happens here?
如果它有一个对象,让我们调用它o
,typeo *a,*b;
如果我将o
两个数组分配给数组a
和数组,b
那么delete[] b
如果我尝试访问 a 中的 o 或 o 会发生什么?例如:
struct name{int a;}
name *a = new name[1];
name *b = new name[1];
name o;
a[0] = o;
b[0] = o;
delete[] b;
a[0]; // what happens here?
如果你只是定义 inta[1]
你没有在堆中分配内存,所以不需要删除。
否则,如果您按如下方式创建数组:
int *a= new int[1]
,则必须删除为
delete [] a;
通过考虑上述两种情况,如果您已为 b 和 a 分配了内存,则可以在删除 b 后安全地访问“a”。
在示例中没有问题。a[0]
并且b[0]
是不同内存位置的不同对象,销毁其中一个对另一个没有影响。
这new
是一条红鲱鱼;以下代码的工作方式相同:
name o;
name a = o;
{
name b = o;
}
a;
name
具有值语义,也就是说,按值复制它会创建一个完全不同的副本。诸如 all 等内置类型int
也具有值语义。
o
如果没有值语义,此代码只会遇到问题;例如,如果它包含资源句柄并且不包含用于复制资源句柄的复制构造函数和赋值操作符代码。
然后复制o
将使两个对象在该资源上具有相同的句柄,如果o
' 的析构函数释放资源,它将留下一个悬空副本。
为了避免这些问题,通常建议将所有类设计为具有值语义。如果该类对不可复制的资源有句柄,则该类应禁用其复制构造函数和赋值运算符以防止意外复制。事实上,资源句柄应该由为资源句柄设计的类来持有。
这有时被称为“三规则”(或自 C++11 起,称为“五规则”或“零规则”)。