Basically, the difference is in the call of the constructor of the object T
, which does not happen in the case of reinterpret_cast
.
When you use the reserved keyword new
to initialize a T
object in a pre-allocated buffer (known as does not make any memory allocations, it only performs the call of the constructor of the object new
, returning the same pointer of the buffer pre-allocated.
When you use T
"forcing" the pre-allocated buffer pointer conversion to a pointer that points to a reinterpret_cast
object, the constructor call of the T
object does not is performed.
In both cases, the destructor of the object T
is never is called because T
only frees the pre-allocated memory from buffer and does not "know" the object delete
.
Here is a functional code that illustrates the difference between the two semantics:
#include <iostream>
class Cachorro {
public:
Cachorro( void ) { std::cout << "Construtor" << std::endl; }
virtual ~Cachorro( void ) { std::cout << "Destrutor" << std::endl; }
void latir( void ) const { std::cout << "Au! Au!" << std::endl; };
};
int main(void) {
//
// placement_params
//
char * buf1 = new char[ sizeof(Cachorro) ];
Cachorro * p1 = new(buf1) Cachorro;
p1->latir();
std::cout << "buf1: " << (void*) buf1 << std::endl;
std::cout << "p1: " << (void*) p1 << std::endl;
delete [] buf1;
//
// reinterpret_cast
//
char * buf2 = new char[ sizeof(Cachorro) ];
Cachorro * p2 = reinterpret_cast<Cachorro*>(buf2);
p2->latir();
std::cout << "buf2: " << (void*) buf2 << std::endl;
std::cout << "p2: " << (void*) p2 << std::endl;
delete [] buf2;
return 0;
}
Output:
Construtor
Au! Au!
buf1: 0x94c010
p1: 0x94c010
Au! Au!
buf2: 0x94c010
p2: 0x94c010
References:
Wikipedia:
link
StackOverflow:
link
cppreference:
link