Reputation: 4410
I'm relatively new to C++ and am having a hard trouble understanding the instantiation of object and pointers to objects.
Whats the difference between these two declaration in terms of memory and usage? :
MyClass obj1;
MyClass *obj2;
And also the specific problem I am having is that I have a class which has an unsigned short array where the last space of the array changes if I do this:
MyClass obj;
obj = MyClass("123");
MyClass has two constructors one which will take an int and as default will assign it to zero and splice it in parts of 3 digits or less. And another which will take a string representation of a number and do the same... hope that makes sense!
It works well if I declare it
MyClass obj = MyClass("123123123");
but not if I do it the other way. Why?
Upvotes: 2
Views: 2685
Reputation: 264441
The difference:
MyClass obj1;
MyClass *obj2;
Here obj1 is an instance of MyClass.
While obj2 can potentially hold the address of an instance of MyClass.
Also obj1 will automatically be initialized by the constructors, while obj2 is not initialized by default (and thus points to random memory). Once initialized obj2 may take the special value NULL which indicates that it is not pointing at an object.
obj2 = &obj1;
Here we initialize obj2 to point at the address in memory of obj1. If you change any of the members of obj1 then you can see the changes by looking at them through obj2 (but because obj2 is a pointer you need to de-reference).
obj1.plop = 5;
std::cout << obj1.plop << "\n";
std::cout << obj2->plop << "\n"; Should print the same values.
The following is actually two different things:
MyClass obj;
obj = MyClass("123");
This line probably works:
MyClass obj = MyClass("123123123");
Because the compiler has optimised this into:
MyClass obj("123123123");
Upvotes: 8
Reputation: 112366
When you say MyClass obj1;
you create the object. MyClass * obj2;
just saves space for the address of the object.
So MyClass obj1;
does the following:
sizeof(MyClass)
bytes of space — could be as big as you wantwhile MyClass * obj2;
instead
obj2
in the symbol tablesizeof(MyClass*)
— probably 4 or 8 bytesWhen you say MyClass obj; obj = MyClass("123123123")
you
MyClass
object for obj using the default ctorMyClass
objectMyClass
object to replace the old one.Upvotes: 3
Reputation: 75635
Two things are affected by these declarations: the lifetime of the variable, and where the memory is allocated.
The pointer version MyClass* is declaring a variable that points at an instance of MyClass. It does not itself allocate it; the allocation from the 'free store' (which is always the same as the 'heap') occurs when you explicitly 'new' it, and is freed when you 'delete' it.
The following code works:
MyClass* test_works() {
MyClass* obj = new MyClass;
return obj;
}
The non-pointer version is allocating the memory in the context it is specified - the declaration might be at a global level, or on the stack in a function, or as a member of another object ('composition') - and it is automatically allocated and freed as it comes in and out of scope.
The following code, for example, will fail:
MyClass* test_crashes() {
MyClass obj;
return &obj;
}
Upvotes: 0
Reputation: 4854
The difference between
MyClass obj1;
MyClass *obj2;
Is the first creates an object (size = size of the object), whereas the second only creates a pointer to an object (4 bytes on 32 bit systems) but not the actual object. In order to do that you'd need to do
MyClass* obj2 = new MyClass("123");
This would allocate 4 bytes for the pointer and the x bytes where x is the size of the object. If you manually "new" something like this, then you are responsible for manually destroying it later using "delete".
The MyClass obj1 will be "destroyed" when it goes out of scope.
Upvotes: 0
Reputation: 89749
In the first code, one actually creates the object of type MyClass so it consumes as much space as needed. the other one just defines a pointer, so you reserve as much space as you would need for an addresss on your system (typically 4 bytes, sometimes 8)
When you split your initialization into two lines, you are first creating MyClass with a default constructor, then creating a MyClass with a parameterized constructor, and then using the assignment operator to override the contents of the first with the contents of the second. This is wasteful. Because constructors can have side effects, the compiler would probably not optimize this for you.
In the third piece of code you provided, you are actually using a single constructor that takes a parameter. Not assignment takes place.
Upvotes: 0
Reputation: 59
When you call
MyClass obj = MyClass("123123123");
You are actually creating two objects! The correct way is to call
MyClass obj("123123123");
Upvotes: 2