My question is influenced by Prof. Thomas Cormen's second comment on his Quora answer$.
He says that the constructor carries out the following three tasks:
Allocates memory for the object.
Initializes the instance variables of the object, e.g., by implicitly calling init in Python. (I also emphasize that the init method should initialize not some, but all of the instance variables.)
Returns a reference to (i.e., address of) the object.
However, the MSDN documentation for C++* says that it is the new operator that does that:
Allocates memory for an object or array of objects of type-name from the free store and returns a suitably typed, nonzero pointer to the object.
My question is, who is right? Or, is there something more to it, perhaps like the new operator always calls the constructor, as suggested by a comment on the post?
Thanks.
$ Unfortunately, Quora does not have the option to copy the link for a comment - I can only do so for the answer.
* Although I say C++, I think it is also true for other languages like Java and C# (I am not 100% sure though).
If you search for constructor on the linked MSDN page, it says this:
When new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated.
In other words, a constructor is called if one exists. If none exists, none is called.
When in doubt, read the specification. From en.cppreference.com
The new expression attempts to allocate storage and then attempts to
construct and initialize either a single unnamed object, or an unnamed
array of objects in the allocated storage. The new-expression returns
a prvalue pointer to the constructed object or, if an array of objects
was constructed, a pointer to the initial element of the array.
Constructor does not allocate memory.
new allocates memory, then calls the proper constructor.
Semi pseudo code here :
template <typename T>
T* new(Args... arguments_to_constructor_of_T_if_any)
{
void* mem = malloc(sizeof(T)); // Allocate memory
// Call constructor
// Compiler will produce machine code to construct object T over memory mem.
(mem) T(arguments_to_constructor_of_T_if_any);
return (T*)(mem);
}
An example :
class A
{
int a;
int b;
A(int a, int b) { this->a = a; this->b = b; };
}
int main()
{
A* a = new A(3, 4);
// After compiled, code above will look like :
void* mem = malloc(sizeof(A));
// Below is A(int, int) constructor
((T*) mem)-> a = 3;
((T*) mem)-> b = 4;
}
Related
I'm a bit rusty at this. I'm trying to figure out exactly what happens with object declaration, values and references, stack and heap. I know the basics, but am unsure about the following examples:
struct MyObject
{
int foo;
MyObject(int val)
{
foo = val;
}
MyObject()//[EDIT] default constructor
{
}
}
//...
//1)
//this reserves memory on the stack for MyObject0 and initializes foo:
MyObject a = MyObject(1); //[EDIT] fixed from comments
//2)
MyObject* b = new MyObject(2);//This I know reserves memory on the heap,
//returns a pointer to it (and calls constructor).
//There are also other ways like malloc or memset.
//3)
MyObject c = *(new MyObject(3));// So here we instantiate MyObject on the heap,
//return a pointer to it but the pointer is dereferenced outside the parenthesis.
//Is c now a newly created value type copy on the stack?
//And is the original new MyObject(3) now inaccessible in the heap memory (leaked)
//because the pointer to it was never stored?
//4)
// void myFunc( MyObject c){}
myFunc(c); //Am I doing a member-wise assignment from c to a new function-scope
//temporary MyObject reserved somewhere else in memory (in a stack frame?)?
//Or am I somehow passing a reference to c even though c is not a pointer or reference?
//[EDIT] myFunc(c); would pass as a reference if I had void myFunc( MyObject &c){}
Finally, if I have a MyObject[] myObjArr1 = new MyObject[10]() I have 10 uninitialized MyObject structs on the heap, and a pointer of type MyObject Array on the heap as well.
How do I declare a MyObject array, on the stack, where the MyObject structs within the array are also on the stack? Or is that not a thing you do?
Let me re-comment on a more precise way:
1) This creates an a variable on the stack initializing it with the value of the temporary MyObject(1), that is created on the stack as a MyObject calling MyObject::MyObject(1) as constructor. The compiler may eliminate the intermediate steps. You can do it simply as MyObject a(1); Note: the = is not an assignment
2) Creates a MyObject on heap by calling MyObject::MyObject(2) and returns a pointer to it, used initialize the b pointer.
Forget about malloc and memset: they allocate memory, but DON'T
CONSTRUCT objects. The sooner you will forgot them, the better for you
and anybody else.
3) a Myobject is created on the heap and constructed by calling Myobkect::Myobject(3), then The new returned pointer is dereferenced and the resulting value used to initialize c by copy. The on-heap created object is "forgotten" in there. (Memory leak: you have no chance to access it further)
4) The object c is copied in the local parameter c of myFunc (in fact the two c are two distinct objects) that will exist into the stack up to the function exit.
I cannot resolve the following issue by myself:
Suppose we are reusing a memory in a following way:
struct A
{
int a;
A(){ }
~A(){ }
};
struct B : A
{
int b;
B(){ }
~B(){ }
};
A *a = (A*) malloc(sizeof(A) + sizeof(B));
B *b = new (a) B; //Constructor of B is calling
The lifetime of object reffered to by a has ended before the constructor of B is starting to call or it has ended when the constructor of B has finished?
You try to use the placement new operator to initialize b. This operator does not call the destructor of class A first (a), but initializes a new one into the memory pointed to by a. This is problematic (as mentioned in the comment), because the sizeof(B) is greater than sizeof(A) and you allocated only sizeof(A) at the pointer a. So it is undefined behavior.
The lifetime of the object a formally does not end. You get something like:
class A { int a; };
void* p = malloc(sizeof(A));
A* a1 = new (p) A();
A* a2 = new (p) A();
I think, you will get something like double called destructor on the same memory, but that is something compiler-implementation specific. I don't think, that the standard does say anything about this.
As soon as you enter the constructor of B, a is not pointing to an object A any more.
The reason is that even before the first instruction of the constructor of an object the runtime already has done the VMT, base sub-objects and member initialization.
Also if the constructor of B doesn't terminate because of an exception the memory has already been used anyway and another object eventually present at the same memory address doesn't exist any more.
In other words just don't do that... in C++ objects are not just a pile of bytes and they have rights; for example the right of having their destructor called ;-)
The standard from the relevant section (3.8) says,
The lifetime of an object of type T ends when:
- if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
- the storage which the object occupies is reused or released.
I interpret to mean that the life time of the object pointed to by a ends when members of B are initialized. Until that happens, the storage is not reused.
The lifetime of a ends when you delete it and not before - since forcing two different objects to occupy the same space this way is itself undefined behaviour and definitely not recommended your compiler may or may not treat that memory as available for reuse and overwrite b.
If you need to have two objects occupying the same location, e.g.: Message Variants or you are trying to write your own debugger then you should use a union type.
The other reason that you are not recommended to do this sort of thing is that you will create a maintenance nightmare. e.g. later in your code you could have:
b.b = 3
while (a.a > 0) {
b.b--;
}
While I understand that this is probably not the best of ideas, I ask hypothetically:
Is it legal to (i.e. defined behavior) to invoke an object's
destructor manually, and then reuse the memory for another object?
Definitions:
class A {
int a, b, c;
A() {}
~A() {}
}
A createObject() {
A object;
return object;
}
Code:
A* object = new A();
// Use object...
object->~A();
*object = createObject();
You can't call the assignment operator on a destroyed object like you are doing. At least not generally, though it might work with some types. What you can do is this though:
A* object = new A();
object->~A();
// Placement new.
// Constructs a new object in the memory pointed to by object pointer.
// Doesn't allocate memory.
new (object) A(createObject());
You can even use placement new to construct objects of a different type in that memory, as long as they fit. Just be sure of two things:
Don't ever construct an object on top of an already existing object that has not been destructed.
Don't ever call delete on a pointer after you've called the destructor on the object it points to until you've re-construced an object (of the same type) in its place.
Calling a destructor explicitly is a legal thing to do - in fact, that's what you do when you use placement new. Initializing an object "in place", when the memory is already allocated, is also a legal thing do do, but you should do it differently: rather than using the assignment operator, you could use this syntax:
object = new (object) A(); // Placement syntax
The way you did it (with an assignment operator) is incorrect, because you are calling a function (i.e. the assignment operator) on an object the destructor of which has completed.
First i am from JAVA.
In java we create class object like this.
Example example=new Example();
The Example class can have constructor or cannot have constructor.
I can use the same in c++ like this
Example* example=new Example();
Where constructor is compulsory.
From this tutorial http://www.cplusplus.com/doc/tutorial/classes/
I got that we can create object like this.
Example example;
Which do not require an constructor.
I have two questions.
What is the difference between both the way of creating class objects.
If I am creating object like Example example; how to use that in an singleton class.
like I usually do like this.
Sample* Singleton::get_sample() {
if (sample == NULL) {
sample = new Sample();
}
return sample;
}
Please guide me if I am wrong.
I can use the same in c++ like this [...] Where constructor is compulsory. From this tutorial I got that we can create object like this [...] Which do not require an constructor.
This is wrong. A constructor must exist in order to create an object. The constructor could be defined implicitly by the compiler under some conditions if you do not provide any, but eventually the constructor must be there if you want an object to be instantiated. In fact, the lifetime of an object is defined to begin when the constructor routine returns.
From Paragraph 3.8/1 of the C++11 Standard:
[...] The lifetime of an object of type T begins when:
— storage with the proper alignment and size for type T is obtained, and
— if the object has non-trivial initialization, its initialization is complete.
Therefore, a constructor must be present.
1) What is the difference between both the way of creating class objects.
When you instantiate object with automatic storage duration, like this (where X is some class):
X x;
You are creating an object which will be automatically destroyed when it goes out of scope. On the other hand, when you do:
X* x = new X();
You are creating an object dynamically and you are binding its address to a pointer. This way, the object you created will not be destroyed when your x pointer goes out of scope.
In Modern C++, this is regarded as a dubious programming practice: although pointers are important because they allow realizing reference semantics, raw pointers are bad because they could result in memory leaks (objects outliving all of their pointers and never getting destroyed) or in dangling pointers (pointers outliving the object they point to, potentially causing Undefined Behavior when dereferenced).
In fact, when creating an object with new, you always have to remember destroying it with delete:
delete x;
If you need reference semantics and are forced to use pointers, in C++11 you should consider using smart pointers instead:
std::shared_ptr<X> x = std::make_shared<X>();
Smart pointers take care of memory management issues, which is what gives you headache with raw pointers. Smart pointers are, in fact, almost the same as Java or C# object references. The "almost" is necessary because the programmer must take care of not introducing cyclic dependencies through owning smart pointers.
2) If i am creating object like Example example; how to use that in an singleton class.
You could do something like this (simplified code):
struct Example
{
static Example& instance()
{
static Example example;
return example;
}
private:
Example() { }
Example(Example const&) = delete;
Example(Example&&) = delete;
Example& operator = (Example const&) = delete;
Example& operator = (Example&&) = delete;
};
Example example;
This is a declaration of a variable named example of type Example. This will default-initialize the object which involves calling its default constructor. The object will have automatic storage duration which means that it will be destroyed when it goes out of scope.
Example* example;
This is a declaration of a variable named example which is a pointer to an Example. In this case, default-initialization leaves it uninitialized - the pointer is pointing nowhere in particular. There is no Example object here. The pointer object has automatic storage duration.
Example* example = new Example();
This is a declaration of a variable named example which is a pointer to an Example. This pointer object, as above, has automatic storage duration. It is then initialized with the result of new Example();. This new expression creates an Example object with dynamic storage duration and then returns a pointer to it. So the example pointer is now pointing to that dynamically allocated object. The Example object is value-initialized which will call a user-provided constructor if there is one or otherwise initialise all members to 0.
Example* example = new Example;
This is similar to the previous line. The difference is that the Example object is default-initialized, which will call the default constructor of Example (or leave it uninitialized if it is not of class type).
A dynamically allocated object must be deleted (probably with delete example;).
There is two ways to make/create object in c++.
First one is :
MyClass myclass; // if you don;t need to call rather than default constructor
MyClass myclass(12); // if you need to call constructor with parameters
Second one is :
MyClass *myclass = new MyClass();// if you don;t need to call rather than default constructor
MyClass *myclass = new MyClass(12);// if you need to call constructor with parameters
In c++ if you use new keyword, object will be stored in heap. it;s very useful if you are using this object long time of period and if you use first method, it will be stored in stack. it can be used only short time period. Notice : if you use new keyword, remember it will return pointer value. you should declare name with *. If you use second method, it doesn;t delete object in the heap. you must delete by yourself using delete keyword;
delete myclass;
1) What is the difference between both the way of creating class objects.
a) pointer
Example* example=new Example();
// you get a pointer, and when you finish it use, you have to delete it:
delete example;
b) Simple declaration
Example example;
you get a variable, not a pointer, and it will be destroyed out of scope it was declared.
2) Singleton C++
This SO question may helps you
First of all, both cases calls a constructor. If you write
Example *example = new Example();
then you are creating an object, call the constructor and retrieve a pointer to it.
If you write
Example example;
The only difference is that you are getting the object and not a pointer to it. The constructor called in this case is the same as above, the default (no argument) constructor.
As for the singleton question, you must simple invoke your static method by writing:
Example *e = Singleton::getExample();
1)What is the difference between both the way of creating class
objects.
First one is a pointer to a constructed object in heap (by new).
Second one is an object that implicitly constructed. (Default constructor)
2)If i am creating object like Example example; how to use that in an
singleton class.
It depends on your goals, easiest is put it as a member in class simply.
A sample of a singleton class which has an object from Example class:
class Sample
{
Example example;
public:
static inline Sample *getInstance()
{
if (!uniqeInstance)
{
uniqeInstance = new Sample;
}
return uniqeInstance;
}
private:
Sample();
virtual ~Sample();
Sample(const Sample&);
Sample &operator=(const Sample &);
static Sample *uniqeInstance;
};
Example example;
Here example is an object on the stack.
Example* example=new Example();
This could be broken into:
Example* example;
....
example=new Example();
Here the first statement creates a variable example which is a "pointer to Example". When the constructor is called, memory is allocated for it on the heap (dynamic allocation). It is the programmer's responsibility to free this memory when it is no longer needed. (C++ does not have garbage collection like java).
In the first case you are creating the object on the heap using new.
In the second case you are creating the object on the stack, so it will be disposed of when going out of scope.
In C++ you'll need to delete objects on the heapexplicitly using delete when you don't Need them anymore.
To call a static method from a class, do
Singleton* singleton = Singleton::get_sample();
in your main-function or wherever.
Take a small example where, I am trying to find out if a variable is allocated on heap or not:
struct A
{
bool isOnHeap;
A () {} // not touching isOnHeap
~A () {}
void* operator new (size_t size)
{
A* p = (A*) malloc(size);
p->isOnHeap = true; // setting it to true
return p;
}
void operator delete (void *p) { free(p); }
};
It gives expected result in g++-4.5 (with warning for stack object). Is it ill defined
to do such operations ?
You can't initialize class members in an overloaded operator new because the object's lifetime hasn't started. You can only initialize members during the construction of the object.
You have no guarantee that the implementation won't wipe the memory between the time operator new returns and the time the object's construction starts or that during object construction members that are specified to have an indeterminate value by the standard (e.g. because they are POD and not explicitly initialized in the constructor like isOnHeap) aren't deliberately set to something by the implementation.
Note that A has a non-trivial constructor (it is user-declared), so its lifetime doesn't start when the storage for the object is allocated (ISO/IEC 14882:2003, 3.8 [basic.life] / 1) and the program has undefined behavior if it uses a pointer to the storage for the object to access a non-static data member (3.8 / 5). Even if A was a POD type, it's value after the completion of the new-expression would still be indeterminate rather than necessarily being related to the values in the bytes in the storage for the object before the new-expression was evaluated.
As Charles said, the object only comes to lifetime after it has been newed, so setting data within your implementation of new is rather dangerous.
Also, when your developers use tools like Lint, there's a big chance that it complains that the member isOnHeap is not initialized in the constructor. If then someone thinks "hey, Lint is right, let's initialize isOnHeap in the constructor of A", this will undermine the mechanism that you try to achieve.
There is a second case of which you probably didn't think. Suppose that someone writes this:
class MyClass
{
public:
...
private:
struct A m_a;
};
int main()
{
MyClass *myVariable = new MyClass();
}
Then your implementation of new will not be called. Nevertheless the instance of A is allocated on the heap (as part of the MyClass instance).
Can you explain why you want to know whether something has been allocated on the heap or not? Maybe there's another, more elegant solution to your problem.
Even when not considering the operator new itself (which is nonstandard and I would even say ugly, but knowing the exact details of some particular compiler it might be workable), there is another problem with this, which renders it useless anyway: You have no guarantee the value od isOnHeap will not be true when allocated on the stack. The stack is not initialized and any garbage from function invocations done before can be found there.