像这样在C++中删除对象时是否存在任何问题?
MyCls* c = new MyCls();
void* p = (void*)c;
delete (MyCls*)p;
像这样在C++中删除对象时是否存在任何问题?
MyCls* c = new MyCls();
void* p = (void*)c;
delete (MyCls*)p;
这段代码是合法的。
将其转换回是关键。如果没有这个,您将调用未定义的行为--MyCls析构函数将不会被调用,并且可能会出现其他问题(如崩溃)。您必须向正确的类型进行强制转换。
还要注意,如果涉及多重继承并使用多个转换,则可能会变得复杂。您的转换必须“匹配”。
如果您的代码结构使您无法在销毁时知道类型,请将每个可删除对象都赋予具有虚析构函数的公共基类。然后在调用delete之前将其转换回基类。
代码定义良好。两个转换都是静态转换,尽管显式地使用static_cast<void*>
等方法而不是使用C样式转换更好。标准规定,如果将对象指针通过静态转换转换为void指针,然后再通过静态转换转换回来,它将保留其原始值。因此,您的最终delete
表达式应具有与delete c
相同的效果。
话虽如此,在C++中使用void*
通常是一种代码异味。
void*
是一个好建议。我有很多故事,都是因为之前的 Java 程序员期望 delete someVoidPointer;
能够正常工作而导致的后续清理工作。 - fluffy虽然这段代码是有效的,但它不是一个好的实践。
一般来说,在代码中不应该出现 new
和 delete
。尝试强制规定只有构造函数可以调用 new
,只有析构函数可以调用 delete
,将有助于更好地组织您的代码。
如果您正在使用 C++11,请始终尝试使用 std::shared_ptr
等,这将自动为您执行上述操作。
void*
类型,然后再转回其原始类型,可以保证其值不变。 - David Schwartz