If you allocate a string
, cast the pointer to a void *
, then delete that, you will be trying to delete a void
thing, not a string
thing. For example, any class that allocates secondary storage (above and beyond the actual object being created with new
) will most likely run into trouble:
#include <iostream>
class Y {
public:
Y() { std::cout << "y constructor
"; }
~Y() { std::cout << "y destructor
"; }
};
class X {
public:
X() { std::cout << "x constructor
"; y = new Y(); }
~X() { delete y; std::cout << "x destructor
"; }
private:
Y *y;
};
int main() {
X *x = new X();
delete (void*)x;
}
This code will "work" in that it's legal but it will not do what you expect:
x constructor
y constructor
And a decent compiler should warn you about it:
program.cpp: In function ‘int main()’:
program.cpp:19:19: warning: deleting ‘void*’ is undefined [-Wdelete-incomplete]
19 | delete (void*)x;
| ^
You should be deleting the type you allocated, to ensure the correct destructor is used. In other words, getting rid of the cast in the code shown above (so that you delete
the correct type) will work out better:
x constructor
y constructor
y destructor
x destructor
Modern C++ has type-safe types which will do the heavy lifting for you, such as variant
or any
(if your single class needs to store a variety of types decided at run-time), or templates (if it can be used for one type but any of a variety). You should investigate those as an alternative to void *
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…