Object creation differences
What is the difference between the 2 following methods to create an object?
Test* t = new Test();
and
Test* t;
Your answers to second sample match with what i thought it would do (no object is created) But
class Test {
public:
void bla(void) {
开发者_如何学C std::cout << "test" << std::endl;
};
};
int main(void) {
Test* test;
test->bla();
}
gives me the output "test"... So there is actually an Object
The first one does 4 things:
- create pointer to
Test
- allocate memory and creates
Test
object (note, that it'sTest
, nottest
) - the new object is value initialized, because of the
()
- see Do the parentheses after the type name make a difference with new? for more information - initializes the pointer to point to the created object
The second one just creates pointer to Test
. And it's not initialized.
@yogi - for your edit - this is totally Undefined Behavior, as the pointer is uninitialized. And no, it's not an object. See C++ function called without object initialization for more information.
The second one doesn't create any object at all and trying to access it will result in Bad Things™.
This is a pointer, allocated on the stack, and uses 32 or 64 bits of memory.
Test * t;
This will create an object of type Test on the heap (an you need to desalocate it)
t = new Test();
This will create an object of type Test on the stack (no need to desalocate it. It will disapear as soon as you exit the current context)
Test t2;
Edit
Your example works because the compiler optimized you code : it notices that you don't use any member, so it could doesn't make the effort you look for the instance.
The first one is a method to create an instance of an object.
The second on is not a method to create an instance of an object. It merely declares a pointer, which remains uninitialised.
After your update: The reason that it still successfully calls bla() is just undefined behaviour. Because that's exactly what the C++ Standard defines what is happening when you work with unsafe memory (in this case some arbitrary address that your pointer is pointing to) - the behaviour is undefined.
As others already said, you're just lucky that the undefined behaviour that you trigger happens to look like what you thought you want (essentially because your Test::bla() is almost like a global free function). To see your example crash and burn, just add some non-trivial class members:
class Test {
public:
void bla(void) {
std::cout << "test: " << x << std::endl;
};
int x;
};
You can think of your original example as a free function
void bla(Test * p) { std::cout << "test" << std::endl; }
which you just happen to call with a garbage parameter, but since you don't use the parameter, nothing bad happens. In my modified example, we try to access p->x
and die.
Test* test;
test->bla();
As other answers have stated, Test* test
does not create any object. It is a uninitialized pointer to Test
. It is not pointing to anything valid unless it is initialized to point to a valid Test
object.
Dereferencing an Uninitialized pointer like you are results in a Undefined Behaior.
In your case it does not crash because you are not referring this
inside bla()
.
Nevertheless its still undefined behavior to dereference unitialized test
.
To reiterate the above point, the following example will mostly crash.
#include<iostream>
class Test
{
public:
int i;
void bla(void)
{
std::cout << "test" << std::endl;
std::cout << "test->i" << this->i <<std::endl;
}
};
int main(void)
{
Test* test;
test->bla();
return 0;
}
精彩评论