我知道使用对象的自我分配并不是一个好主意,显然没有人明确地做过这样的自我分配。
MyClass obj;
obj = obj;
有什么理由说C ++支持这个或者是否有任何特殊情况可以使用它?
答案 0 :(得分:2)
除了Carl Norum和Ralph Tandetzky已经发布的答案之外,还要问问自己编译器是否可以检测所有可能的自我分配。
答案应该是显而易见的,不,不可以。考虑一下这个相当简单(而且很愚蠢)的代码片段:
Class obj1;
Class obj2;
Class *ptr = &obj1;
if((rand() % 7) == 0)
ptr = &obj2;
obj2 = *ptr;
此代码有时会导致自我分配。编译器应该警告你吗?什么? “海森堡错误#3:当rand()
返回7的倍数时自我指定?”如果您的rand
仅返回[0,6]范围内的数字怎么办? / p>
这是一个简单的示例,编译器可以很容易地弄清楚。有更复杂的代码片段会更难以捕获,但如果编译器执行广泛流程分析代码但是运行起来需要更长时间,则可能会被捕获。而且,当然,有一些非常复杂的代码片段可以表现出这种非常难以甚至无法捕获的行为。
所以,你可能有一个编译器需要花费更长的时间来运行,有时候概率性地警告你有关潜在的自我分配。坦率地说,这比没有警告更糟糕。
如果你认为这是一个问题并且你不想允许它,那么你的编码标准应该是“没有自我分配!”可能是更好的主意。
Sidenote :有些工具可以进行大量非常复杂的源代码分析,以尝试根除问题;这些工具可以配置为并将捕获许多这样的自我分配,包括一些复杂的自我分配。但他们仍然没有抓住所有东西,需要一段时间才能运行,通常花费数千美元。
答案 1 :(得分:1)
我想没有理由禁止它。你为什么这样?要创建额外的语言规则?据我所知,没有真正使用自我分配。
有充分的理由允许在作业的两边都有一个对象,例如
obj = f( obj );
该行
obj = obj;
实际上只是一个特例。
答案 2 :(得分:0)
我认为这是可能的。就像你可以在汇编中移动相同寄存器本身的值:
mov eax, eax
它恰好适用于普及的设计。
答案 3 :(得分:0)
这可能是允许的,因为没有真正的理由不允许它。我已经看到它用作未使用变量警告的解决方法,但我不建议个人使用。
答案 4 :(得分:0)
对于没有构造函数的POD对象或对象,它可用于抑制“may be used before initialized
”警告(如果声明的局部变量确实未使用,则应该将其删除)。
当处于文件或命名空间范围时,它可以用作 hack ,以防止初始化其他全局对象的构造函数正在使用的全局对象。
std::list<Foo> g_foos;
如果Foo
的静态实例在g_foos
运行之前将其自身添加到g_foos::g_foos()
,则列表将自行清空,并且注册将丢失。自我初始化可以防止这种情况。
std::list<Foo> g_foos = g_foos;
但是有更好的方法来实现也可以防止此问题的全局实例,例如:
std::list<Foo> & the_foos () {
static std::list<Foo> foos;
return foos;
}