Understanding the Constructor Concept

I don't understand what constructor means in C ++ formally. I was reading Proposition 3.8 (Object Lifetime, N3797) and came across the following:

An object is said to have non-trivial initialization if it has a class or collection and it or one of its members is initialized to a constructor other than the trivial default constructor.

I would like to understand initialization in general. I was reading section 8.5, N3797. Is it true that if some object is initialized, the constructor (perhaps trivial by default) will be called? I mean every initialization process (even null initialization) means a constructor call. It would be nice if you could provide relevant references to the standard.

+3


source to share


6 answers


I don't understand what contructor means formally in C ++.

As far as I know, the standard does not explicitly define the term "constructor". However, §12.1 / 1 says:

Constructors are unnamed. A special declarator syntax is used to declare or define a constructor. The syntax uses:

  • an optional spec-specifier-seq in which each spec is either a function specifier or constexpr

    ,
  • constructor class name and
  • parameter list

in that order. In such a declaration, the optional parentheses around the constructor class name are ignored.

Thus, if you declare a member function according to this syntax, the function you are declaring is a constructor. Besides,

Default constructor (12.1), copy constructor and copy assignment operator (12.8), move constructor and move assignment operator (12.8), and destructor (12.4) are special member functions. [Note the implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them. The implementation will implicitly define them if they are used by odr (3.2). See 12.1, 12.4 and 12.8. - end note] Programs should not define implicitly declared special member functions.

(§12 / 1)

So there you go - every class has at least three constructors, both implicitly and explicitly declared; and you can also declare other constructors using the syntax in §12.1 / 1. Thus, the entire set of declared functions forms a set of constructors.



Is it true that if some object is initialized, the constructor (perhaps trivial by default) will be called? I mean every initialization process (even null initialization) means a constructor call.

No, this is not true. For example, int

it has no constructors. This is despite the fact that you can initialize int

with a similar syntax as compared to initializing objects of the class type.

struct Foo {};
Foo f {}; // calls default constructor
int i {}; // sets the value of i to 0

      

Also, null initialization never invokes a constructor, but null initialization is also never the only step in initializing an object.

If by "object" you meant "object of class type", it is still not true that a constructor is always called, although three constructors are always declared as above. See §8.5 / 7 about value initialization:

To initialize the value of an object, type T

means:

  • if it T

    is a (possibly cv-qualified) class type (section 9) with a user-supplied constructor (12.1), then the default constructor for is called T

    (and the initialization is ill-formed if T

    there is no default constructor available);
  • if it T

    is a (possibly cv-qualified) non-union class without a user-supplied constructor, then the object is initialized to zero and if the T

    implicitly declared default constructor is non-trivial, that constructor is called.
  • If T

    is an array type, then each element is value-initialized;
  • otherwise, the object is initialized to zero.

Hence, when the default constructor for the type of a nonunited class is trivial, and you initialize an object to that type, the constructor is not really called.

+3


source


The constructor is a special function. This looks like a normal function. It has no return type (although some say the return type is a class object) like void, int, char, double, etc. It has the same name as the class name. It starts automatically when the object is created. In C ++, you don't need a new operator to initialize an object. Just declare it and set its attribute. those.ClassA object1, object2;

for example

Class Player{
int jerseyNo;

//constructor
Player(){
cout<<"HELLO";
}
};

      

Basically you can do the following:

Player nabin;

      

And you can declare a destructor . A destructor is a special function, similar to a constructor, but executed when the object is destroyed, i.e. When the object goes out of scope.



Example:

Class Player{
..
~Player(){
cout<<"Destructor ran";
}
..
};

      

PS The order of execution of the constructor and destructor is reversed. Example:

Player p1,p2,p3;

      

The order of their implementation

1. p1 constructor runs
2. p2 constructor runs
3. p3 constructor runs
4. p3 destructor runs
5. p2 destructor runs
6. p1 destructor runs

      

0


source


Classes are types:

A class is a type.

§9 [class]

However, not all types are classes. The standard refers to types that are not class types (such as scalar types) in section 3.9.

Only class types can have member functions:

Functions declared in a class definition, other than those declared using a qualifier friend

, are called member functions of that class.

§9.3 [class.mfct]

Constructors are member functions. Therefore, there may be types without constructors (i.e., Types that are not class types). Therefore, initialization does not necessarily involve calling a constructor, since non-class types ( int

for example) can be initialized.

Note that something doesn't have to be a class type to be an "object":

An object is a storage area.

§1.8 [intro.object]

Hence, int

not being a class will be an "object".

0


source


You asked:

Is it true that if some object is initialized, the constructor (perhaps trivial by default) will be called?

The short answer is: No.

Longer answer: The constructor is only called for class type objects. For objects of other types, there are no constructors, and therefore constructors cannot be called.

You said:

I mean every initialization process (even null initialization) means a constructor call.

Objects of class types can be initialized by calling constructors, which can be explicit or implicit. They can also be initialized with other initialization methods. Objects of other types are initialized by directly setting the initial values ​​of the memory they occupy.

You have already seen section 8.5 of the draft standard on initialization.

Details on class constructors can be found in section 12.1 Constructors .

Details of class initialization can be found in section 12.6 Initialization .

0


source


I think your answer will be found in 3.6.2 and 8.5 from N3797.

The constructor is always called when an object is created. But object initialization is a multi-step process.

I understand that Zero-Initialization is separate and done as the first step during object initialization, the constructor (probably trivial by default) is called later

0


source


Basically, whenever you create a data type in C ++, it can happen in one of two ways. You can either call the constructor or you can copy chunks of memory. Therefore, constructors are not always named.

There is a concept of primitives in C ++. Integers, doubles, pointers, symbols, pointers (to something) are all primitives. Primitives are data types, but they are not classes. All primitives are copy-safe in a bitwise fashion. When you create or assign primitives, the constructor is not called. All that happens is some assembly code is generated that copies some bits.

With classes, it's a little more complicated; the answer is that the constructor is usually called, but not always. In particular, C ++ 11 has the concept of trivial classes. Trivial classes are classes that satisfy several conditions:

  • They use default values ​​for all "special" functions: constructor, destructor, move, copy, assign.
  • They have no virtual functions.
  • All non-static members of a class are trivial classes or primitives.

As of C ++ 11, objects of any class that satisfy this requirement can be treated as chunks of data. When you create such an object, the constructor will not be called. If you create such an object on the stack (without a new one), its destructor will also not be called at program termination, as it would normally be called.

Don't take my word for it. Take a look at the assembly generated for the code I wrote . You can see that there are two classes, one is trivial and the other is not. A non-trivial class has a call to its constructor in an assembly, a trivial one does not.

0


source







All Articles