Is a constructor a function and is it possible to call a constructor
Asked Answered
A

3

6

I came across this where one of the user comment says:

A constructor cannot be called, it is not a function. It is invoked automatically when a new object is created.

My question is that is the above comment true/correct? If yes, then why isn't a constructor considered a function and why can't we call it?

Adalai answered 30/3, 2022 at 16:7 Comment(6)
A constructor is a special member function. It can only be called to construct an object. Is this satisfying or are you looking for a more in depth answer?Ensconce
You might be interested in placement new, which is what happens when you allocate the memory for an object yourself, but then "call the constructor" to get the object initialized.Phonetics
This has changed @ c++11 I believe. It used to be partially true. Related: https://learn.microsoft.com/en-us/cpp/cpp/delegating-constructors?view=msvc-170Situate
@Situate please put that below. Until somebody puts a post together mentioning Delegating Constructors, their answer is incomplete. As of this writing none of them below mention it.Pillion
@KevinAnderson: There's not really anything special about delegating constructors, compared to initialization of base class subobjects and member subobjects. It still is not a direct function call.Stipitate
Here's a similar question, if your intent of calling the constructor is to "re-initialize" an object (which seems to be a common motivation for doing what you propose.)Phonetics
S
16

Formally in the C++ Standard it is (along with several others) a special member function so yes it is a function, but it is a special function and not all of the normal rules apply.

There is no syntax to write code that calls a constructor directly or forming a function pointer to it. The Standard specifically says "Constructors do not have names."

The compiler will automatically call a constructor when an object is created. The compiler will also automatically call constructors for subobjects (bases and members) of a class object. "Delegating constructors" are sort-of a degenerate case of initialization of subobjects (In formal algebra, we say that any set is a subset of itself, and say "strict" subset when we mean a subset that is not the entire set).

There are a variety of ways to create an object and some of them look like a function call, but that's actually a cast and results in creation of a new object, on which the constructor is called implicitly by the compiler. There's also placement-new syntax which doesn't do very much besides causing the compiler to implicitly call the constructor -- but even there a brand new object is being created.

One important way in which the compiler's implicit call to a constructor differs from an explicit function call found in user code is that the implicit call occurs within an implicit try/catch scope that will result in destruction of subobjects if an exception occurs. A direct call to the constructor, if one were possible, wouldn't have such extra behavior.

Stipitate answered 30/3, 2022 at 16:10 Comment(4)
At the end of your answer, you mentioned that "implicit call occurs within an implicit try/catch scope..". Can i read more about this particular topic somewhere. I mean i have read some books on C++ like C++ Primer by Lippman etc, but there i couldn't find this implicit try/catch scope. Can you suggest some reference to me about this so that i can learn more about it and how the implicit call occurs within an implicit try/catch scope. Also, is this behavior compiler dependent or the C++ standard says that the implicit call occurs within an implicit try/catch scope?Adalai
@Mike isocpp.org/wiki/faq/exceptions#ctors-can-throwEnsconce
@Ensconce I still don't get the last part of the answer. I mean i know the basics about exceptions but i don't get the statement "the implicit call occurs within an implicit try/catch scope". Is the compiler "required to" create an implicit try/catch scope. Additionally, why/how wouldn't a direct call to the constructor, if one were possible wouldn't have such extra behavior.Adalai
@Mike The meaning of "direct" call excludes extra behavior (proxies, wrappers, trampolines). Here is where you can read the rules for that extra behavior: eel.is/c++draft/except.ctor Of course the Standard only says what the compiler must make happen and not how, it doesn't say a try/catch is needed, it just says that certain things must happen if the constructor exits abnormally due to an exception'.Stipitate
A
2

The quoted comment is incorrect. A constructor is a special member function. And it can be implicitly called by the compiler at the time of object creation.

For example,

struct A 
{   
};
int main()
{
//----v----->note the absence of parenthesis like when we call a function
    A a; //creates object of type A by implicitly calling the default constructor
}

These are some of the special(things to be noted) things about constructors:

  1. They don't have return types.
  2. They are automatically synthesized by the compiler given certain conditions are satisfied.
  3. They are implicitly called by the compiler at the time of object creation.
Adalai answered 30/3, 2022 at 16:10 Comment(2)
It can only be called by the compiler, there's no way for you to call it.Stipitate
@BenVoigt Indeed.Adalai
H
2

When I was using an "union" of objects where I had to manage the destruction and construction of the members of the union, I was able to call the constructor like this using the "new operator":

new(&variable) NameOfTheClass

#include <iostream>
class A {
    public: A() {std::cout << "constructor called for pointer " << this << std::endl;}
};

int main() {
   A a;
   new(&a) A; //Should call a second time the constructor
}
Heterogenetic answered 1/4, 2022 at 7:35 Comment(4)
But if I am not mistaken, this is "creating" a new object on the address of "a" (i.e., the compiler does not reallocate any memory). However, is not calling a constructor, by definition, creating/"resetting" the object to its default value?Heterogenetic
It is not a call to a constructor, it is creating a new object reusing the memory of the old one. Creation of a new object will run the constructor among several other tasks.Stipitate
@BenVoigt: Sure, it will "create a new object reusing the memory", but I am also thinking more in C where the "constructor" is the equivalent of the "init" function of "every" object you allocated (using, e.g., malloc). Is not "calling" a constructor, by definition, constructing an object (and thus, if you recall it, you just reinitialize it)? I am not aware of the other tasks the compiler does, and I do not know if those are part of the standard or not.Heterogenetic
There is no "reinitialize" an object. There is no way to call, even indirectly (by doing something that induces the compiler to call it, like placement-new), a constructor on an existing object. The object on which the constructor runs is a brand-new object, any members without initialization become uninitialized, they do not retain previous values. The old object ends and a new one begins. C++ draws a major distinction between a constructor and "init" performed by an ordinary function, the former is special and tightly integrated into object lifetime rules.Stipitate

© 2022 - 2024 — McMap. All rights reserved.