7

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:

  1. Allocates memory for the object.

  2. 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.)

  3. 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).

Community
  • 1
  • 1
P.K.
  • 379
  • 1
  • 4
  • 16
  • Don't know why you think those two quotes are mutually exclusive :) – Rakete1111 May 17 '18 at 17:43
  • 3
    I don't think I'm seeing what you expected to share from your first link. – François Andrieux May 17 '18 at 17:43
  • @FrançoisAndrieux, sorry, I didn't get you. I just used the link because I was quoting someone else. I have actually copied what he says into my question. – P.K. May 17 '18 at 17:44
  • Possible duplicate of [When is the constructor called by 'new' operator in C++](https://stackoverflow.com/questions/19472418/when-is-the-constructor-called-by-new-operator-in-c) – Thomas Cohn May 17 '18 at 17:44
  • 1
    Perhaps the two passages are talking about different uses of the `new` keyword. There is [`operator new`](http://en.cppreference.com/w/cpp/memory/new/operator_new) and there are [`new expressions`](http://en.cppreference.com/w/cpp/language/new). `operator new` allocates, doesn't call the constructor and can be overwritten, `new expressions` (usually) allocates with `operator new` and calls the constructor. – François Andrieux May 17 '18 at 17:44
  • Further in the MSDN article: _"When new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated."_ – Drew Dormann May 17 '18 at 17:44
  • @Rakete1111, could you please elaborate? – P.K. May 17 '18 at 17:45
  • @P.K. Basically what Francois said :) – Rakete1111 May 17 '18 at 17:45
  • If constructors allocated the object's memory, placement new would be utterly broken. – chris May 17 '18 at 17:45
  • 1
    @P.K. The context for that passage seems important, but I can't find your citation using the provided link. – François Andrieux May 17 '18 at 17:45
  • @FrançoisAndrieux, it is in the comments (the second comment to be precise). – P.K. May 17 '18 at 17:45
  • 1
    Possible duplicate of [Differences Between Python and C++ Constructors](https://stackoverflow.com/questions/4025913/differences-between-python-and-c-constructors) – Sean Munson May 17 '18 at 17:46
  • Why can't a Python constructor works as the professor described, and C++ new operator and constructor works differently? I fail to see what comparing construction mecanisms between two languages achieves. – MartinVeronneau May 17 '18 at 17:55

3 Answers3

5

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.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • Sorry, this confuses me. If a constructor is not defined, then in Cormen's words, who (or what) will carry out the three tasks? – P.K. May 17 '18 at 17:50
  • 1
    A class type's constructor is always called and must exist, otherwise using `new` would be ill-formed. Though, that constructor may be empty and implicitly generated. – François Andrieux May 17 '18 at 17:51
  • 1
    A bit of clarify with "if none exists": A default constructor does exist. – Ripi2 May 17 '18 at 17:51
  • @Ripi2 A default constructor might not exist (ex. `struct foo { foo() = delete; };`), but there must exist a constructor that matches the arguments provided to `new`. – François Andrieux May 17 '18 at 17:52
  • @Ripi2, yes, then it makes sense to me. – P.K. May 17 '18 at 17:52
  • @P.K. Non-class types in C++ don't have constructors. C++ also has *trivial* constructors that do nothing. If nothing initializes an object in C++, then it is illegal to read from it or copy it. (Illegal meaning that doing so results in **undefined behavior**.) – Potatoswatter May 17 '18 at 17:53
  • @Potatoswatter, okay, then that makes the number of activities of the constructor _two_. What about the first task - memory allocation? Is it done by `new` and not the constructor? I think the quote in your answer subtly says this. – P.K. May 17 '18 at 17:56
  • More clarify: There are trivial ctors. You can have several, overloaded, ctors. You can leave the compiler to create a default ctor. You can avoid this default creation. Use the best for each case- – Ripi2 May 17 '18 at 17:56
  • @P.K. Memory allocation is done by a function named `operator new` (somewhat confusingly). Then the constructor is a separate call. – Potatoswatter May 17 '18 at 17:57
  • 2
    @P.K. The constructor may only be called after memory has been allocated. Conceptually, it can't be responsible for allocating that memory. It's the `new operator` for that class, which is called by the `new expression`, that allocates the memory. – François Andrieux May 17 '18 at 17:57
  • @FrançoisAndrieux, thank you for the precise comment. It is helpful. – P.K. May 17 '18 at 18:00
3

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.

Ripi2
  • 7,031
  • 1
  • 17
  • 33
1

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;
}
vkx
  • 424
  • 1
  • 7
  • 17