Is there an implicit default constructor in C ++?

The book I'm reading right now ( C ++ Without Fear ) says that if you don't declare a default constructor for the class, the compiler supplies one for you, which "nullifies every data item." I have experimented with this and I do not see any nullifying behavior. I also cannot find anything that mentions this on Google. Is this just a bug or a quirk of a particular compiler?

+58
c ++ constructor
Feb 18 '09 at 22:56
source share
11 answers

If you do not define a constructor, the compiler will define a default constructor for you.

Implementation of this

default constructor:

  • default build a base class (if the base class does not have a default constructor, this is a compilation error)
  • default builds each member variable in declaration order. (If a member does not have a default constructor, this is a compilation error).

Note:
POD data (int, float, pointer, etc.) does not have an explicit constructor, but the default action does not mean anything (in the C ++ philosophy weather vane, we don’t want to pay for something unless we explicitly ask for it )

If the destructor / copy Constructor / Assignment operator is not defined, the compiler builds one of them for you (therefore, the class always has the / Copy Constructor / Assignment Operator descriptor (unless you cheat and explicitly declare one, but do not define it)).
Default implementation:

Destructor:

  • If a user-defined destructor is defined, execute the provided code.
  • Call the destructor of each member in the reverse order of declaration
  • Call the base class destructor.

Copy constructor:

  • Calling the copy constructor of the base class.
  • A call to the copy constructor for each member variable in the declaration order.

Assignment Operator:

  • Call base class assignment operator
  • Invokes the assignment operator for each member variable in the declaration order.
  • Return link to this.

Note. The POD Data copy / assign statement simply copies the data (hence the shallow copy problem is related to RAW pointers).

+60
Feb 18 '09 at 23:21
source share

I believe it is worth noting that the default constructor will only be created by the compiler if you provide any constructor . This means that if you provide only one constructor that takes an argument, the compiler will not create a default no-arg constructor for you.

The nulling your book talks about is probably specific to a particular compiler. I always assumed that it could change and that you should explicitly initialize any data elements.

+35
Feb 19 '09 at 0:10
source share
  • Does the compiler create a default constructor?
  • Does the implicitly created default constructor create zero initialization?

If you legally understand the language of the 2003 standard, the answers are yes and no . However, this is not the whole story , because, unlike the default user constructor, the implicit default constructor is not always used when creating an object from scratch - there are two other scenarios: no construction and initialization of the element value.

The case with the lack of construction is just technicality, because it is functionally no different from calling the trivial default constructor. Another case is more interesting: member value initialization is initiated using "()" [as if explicitly calling a constructor that has no arguments], and it bypasses what is technically called the default constructor . Instead, it recursively initializes the values ​​for each data item, and for primitive data types, this ultimately allows zero initialization .

Thus, the compiler provides two different implicitly defined default constructors . One of which performs zero initialization of the data of a primitive element, and the other does not. Here are some examples of how you can call each type of constructor:

MyClass a; // default-construction or no construction MyClass b = MyClass(); // member-wise value-initialization 

and

  new MyClass; // default-construction or no construction new MyClass(); // member-wise value-initialization 

Note. If there is a default constructor declared by the user , then the initialization of values ​​by elements simply calls this and stops.




Here are some detailed breakdowns of what the standard says about it ...

  • If you do not declare a constructor, the compiler implicitly creates a default constructor [12.1-5]

  • The default constructor does not initialize primitive types [12.1-7]

     MyClass() {} // implicitly defined constructor 
  • If you initialize the object with "()", this does not directly call the default constructor. Instead, it initiates a long sequence of rules called value initialization [8.5-7]

  • The net effect of initializing a value is that an implicitly declared default constructor is never called . Instead, initialization initialization is called using a recursive element, which ultimately initializes to zero any primitive elements and calls the default constructor for any members that have a constructor declared by the user [8.5-5]

  • Value initialization applies even to primitive types — they will be initialized to zeros. [8.5-5]

     a = int(); // equivalent to int a=0; 



All this is really a moot point for most purposes. A class writer usually cannot assume that data members will be nullified during an implicit initialization sequence, so any self-checking class must define its own constructor if it contains primitive data elements that require initialization.

So, when does it matter?

  • There are times when common code wants to force initialization of unknown types. Initialization of initialization makes it possible to do this. Just remember that implicit null initialization does not occur if the user provides a constructor.

  • By default, the data contained in std :: vector is initialized with a value. This may prevent memory debuggers from identifying logical errors associated with other uninitialized memory buffers.

     vector::resize( size_type sz, T c=T() ); // default c is "value-initialized" 
  • Entire arrays of primitive types or simple-old (POD) structures can be initialized to zero using value initialization syntax.

     new int[100](); 



This post contains more detailed information about the options between versions of the standard, and also notes the case when the standard is applied differently in the main compilers.

+32
Feb 13 '11 at 5:59
source share

C ++ creates a default constructor, but only if you do not provide your own. The standard does not say anything about zeroing data members. By default, when you first create any object, they are undefined.

This can be confusing because most C ++ DO primitive types have standard “constructors” that initialize them to zero (int (), bool (), double (), long (), etc.), but the compiler doesn’t call them for init POD elements, as it does for the members of an object.

It is worth noting that STL uses to use these constructors by default - it constructs the contents of containers that contain primitive types. You can take a look at this question for more details on how things get in STL containers.

+20
Feb 18 '09 at 22:58
source share

The default constructor created for the class will not initialize the built-in types, but it will call the default constructor for all user-defined elements:

 class Foo { public: int x; Foo() : x(1) {} }; class Bar { public: int y; Foo f; Foo *fp; }; int main() { Bar b1; ASSERT(b1.fx == 1); // We know nothing about what b1.y is set to, or what b1.fp is set to. // The class members' initialization parallels normal stack initialization. int y; Foo f; Foo *fp; ASSERT(fx == 1); // We know nothing about what y is set to, or what fp is set to. } 
+11
Feb 18 '09 at 23:20
source share

The compiler will generate default constructors and destructors if they are not created by the user. They will NOT change the state of any data items.

In C ++ (and C), the contents of any highlighted data are not guaranteed. In debug configurations, some platforms set this value to a known value (for example, 0xFEFEFEFE) to help identify errors, but you should not rely on it.

+5
Feb 18 '09 at 23:03
source share

C ++ does not guarantee zeroing of memory. Java and C # do (in a manner of speaking).

Some compilers can, but do not depend on it.

+4
Feb 18 '09 at 22:58
source share

Zero occurs only for global variables. Therefore, if your object is declared in the global scope, its members will be null:

 class Blah { public: int x; int y; }; Blah global; int main(int argc, char **argv) { Blah local; cout<<global.x<<endl; // will be 0 cout<<local.x<<endl; // will be random } 
+4
Feb 18 '09 at 23:07
source share

C ++ generates a default constructor. If necessary (determined at compile time, I reckon), it will also generate a default copy constructor and a default destination constructor. I have not heard anything about memory reset guarantees.

+1
Feb 18 '09 at 23:00
source share

The default compiler will not generate a default constructor if its implementation does not require. So basically the constructor should be a non-trivial constructor .

In order for the constructor to be a non-trivial constructor, the following conditions, which may be sufficient:

1) The class has a virtual member function. 2) Sub-objects of a class or base classes have non-trivial constructors. 3) The class has a virtual inheritance hierarchy.

0
Oct 30 '13 at 8:58
source share

In C ++ 11, the default constructor generated by the compiler is marked as remote if:

  • the class has a reference field
  • or constant field without custom default constructor
  • or a field without a default initializer with a remote default constructor

http://en.cppreference.com/w/cpp/language/default_constructor

0
Jan 12 '16 at 23:15
source share



All Articles