A detailed description of constructors in C + + and explicit invocation of constructors

Source: Internet
Author: User

A detailed description of C + + constructors and explicit invocation of constructors for C + + classes

What is a constructor?

Class Counter
{
Public
Constructors for class counter
Features: Class name as function, no return type
Counter ()
{
m_value = 0;
}
Private
Data members
int m_value;
}
When the class object is created, the compiled system object allocates memory space and automatically calls the constructor, which is done by the constructor to complete the initialization of the member
Eg:counter C1;
The compilation system allocates memory space for each data member (M_VALUE) of the object C1, and calls the constructor counter () to automatically initialize the object C1 m_value value is set to 0
So
constructor function: Initializes the data member of the object.
Ii. types of constructor functions
Class Complex
{
Private:
Double m_real;
Double M_imag;
Public
Parameterless constructors
If you create a class and you do not write any constructors, the system automatically generates the default parameterless constructor, the function is empty, and nothing is done
As long as you write one of the following constructors, the system will no longer automatically generate such a default constructor, if you want to have an argument-less constructor, you need to write it yourself.
Complex (void)
{
M_real = 0.0;
M_imag = 0.0;
}
General constructors (also called overloaded constructors)
General constructors can have a variety of parameter forms, a class can have more than one general constructor, if the number of parameters or different types (based on the principle of overloaded functions of C + +)
For example: You can also write a Complex (int num) constructor.
Different constructors are called depending on the parameters passed in when the object is created
Complex (double real, double imag)
{
M_real = Real;
M_imag = Imag;
}
Copy constructors (also known as copy constructors)
A copy constructor parameter is a reference to the class object itself that copies a new object of that class based on an existing object, typically copying the value of the data member of an existing object into the newly created object in the function
If you do not see a write-copy constructor, the system creates a copy constructor by default, but when there are pointer members in the class, there is a risk that the copy constructor is created by default, for specific reasons, please inquire about "shallow copy", "Deep copy" article discussion
Complex (const Complex & c)
{
Copy the value of the data member in Object C.
M_real = C.m_real;
M_imag = C.m_imag;
}
A type conversion constructor that creates an object of this class based on an object of a specified type.
One thing to note is that this is actually a general constructor, but for a constructor that has such a single parameter, C + + will by default convert the type of the argument to that class type, and sometimes this kind of privacy conversion is something we don't want, so we need to use explicit to limit the conversion. For example: The following will create a Complex object based on an object of type double Complex (double R)
{
M_real = R;
M_imag = 0.0;
}
equals operator overload (also called assignment constructor)
Note that this is similar to the copy constructor, which copies the value of the object of this class = Right to the object to the left of the equals sign, which is not a constructor, and the object on both sides of the equal sign must have been created
If the Write = operator overload is not displayed, the system also creates a default = operator overload, doing only basic copy work
Complex &operator= (const Complex &RHS)
{
First detect whether the right side of the equal sign is the left object itself, and if the object itself, return directly
if (this = = &RHS)
{
return *this;
}
Copy the member to the right of the equal sign to the left object
This->m_real = Rhs.m_real;
This->m_imag = Rhs.m_imag;
Send the object to the left of the equal sign again
The purpose is to support the EG:A=B=C system to run first B=c
Then run a= (the return value of B=c, which should be the B object after the C value is copied)
return *this;
}
};

The following uses the class object defined above to illustrate the use of each constructor:
int main ()
{
Call the parameterless constructor, the initial value of the data member is assigned to 0.0
Complex c1,c2;

Call General constructor, data member initial value is assigned
Complex C3 (1.0,2.5);
You can also use the following form
Complex C3 = Complex (1.0,2.5);

Assigns the value of the C3 data member to C1
Since C1 has been created beforehand, no constructors will be called
Only the = number operator overload function is called
C1 = C3;
Invoking a type conversion constructor
The system first invokes the type conversion constructor, creates 5.2 as a temporary object of this class, and then calls the Equals operator overload to assign the temporary object to C1
C2 = 5.2;
Call copy constructor (there are two ways to call)
Complex c5 (C2);
Complex C4 = c2; Note and = operator overloading is distinguished, where the object to the left of the equals sign is not created beforehand, so the copy constructor needs to be called and the argument is C2
This is especially important, here is the initialization, not the assignment. In fact, this involves two types of initialization in C + +: Copy initialization and assignment initialization. Where c5 is used for replication initialization, and C4 uses assignment initialization, both of which are called copy constructors.
}

third, thinking and testing
1. Carefully observe the copy constructor
Complex (const Complex & c)
{
Copy the value of the data member in Object C.
M_real = C.m_real;
m_img = c.m_img;
}
Why are private members of object C directly accessible in the function?
Answer: (online) because the copy constructor is placed in the class itself, and the function in the class can access all members of the object of the class, including, of course, private members.
2. Challenge, understand the difference between reference and value
Complex test1 (const complex& c)
{
return C;
}
Complex test2 (const Complex c)
{
return C;
}
Complex Test3 ()
{
Static Complex C (1.0,5.0);
return C;
}
complex& test4 ()
{
Static Complex C (1.0,5.0);
return C;
}
void Main ()
{
Complex A, B;
The constructor is called several times during the execution of the function, and what constructor is called?
Test1 (a);
Test2 (a);
b = test3 ();
b = test4 ();
Test2 (1.2);
Does the following statement make an error?
Test1 (1.2); Test1 (Complex (1.2))?
}
A: To make it easier to see the effect of the call to the constructor, I will change the class to add some output information, the code is as follows:
View CodeThe following is the result of the program running: Results of the 3rd run of the first run result 2nd run result

Iv. Appendices (Shallow copy and deep copy)

As mentioned above, if there is no custom copy constructor, the system creates a default copy constructor, but the system creates a default copy constructor that only performs a "shallow copy" that assigns the value one by one of the data member of the copied object to the newly created object, if there are pointer members in the data member of the class. The pointer to the new object points to the same address as the pointer to the copied object, and the delete pointer causes two repetitions of the delete error. Here's an example:
"Shallow copy and deep copy"
#include <iostream.h>
#include <string.h>
Class Person
{
Public:
constructor function
Person (char * pN)
{
cout << "General constructors are called!\n";
M_pname = new Char[strlen (PN) + 1];
Open up a memory block in the heap to hold the string referred to by the PN
if (m_pname! = NULL)
{
If M_pname is not a null pointer, copy the string referred to by the parameter-pointer pn to it
strcpy (M_pname, PN);
}
}

System-created default copy constructor, only bit-mode copy
Person (person & P)
{
To point two string pointers to the same address location
M_pname = P.m_pname;
}
~person ()
{
Delete M_pname;
}
Private:

char * M_PNAME;
};

void Main ()
{
Person man ("Lujun");
Person Woman (Mans);

As a result, both man and woman pointers point to the same address

When the function ends the destructor
Delete two times with same address
}
The following is the design of the copy constructor to implement "deep copy", that is, not to point the pointer to the same address, but to re-request a piece of memory to the new object pointer data member
Person (person & CHS);
{
Allocating space for pointer data members of new objects with operator new
M_pname=new Char[strlen (P.m_pname) + 1];

if (m_pname)
{
Copy content
strcpy (M_pname, chs.m_pname);
}

Then the m_pname of the newly created object and the M_pname of the original object CHS no longer point to the same address.
}

Reference Address: http://ticktick.blog.51cto.com/823160/194307

An important issue discussed below is the explicit invocation of constructors

Let's see what the output of this piece of code is. Is there a problem with this piece of code?

#include <iostream>
Class CTest
{
Public
CTest ()
{
M_a = 1;
}
CTest (int b)
{
M_b = b;
CTest ();
}
~ctest ()
{}
void Show
{
Std::cout << m_a << Std::endl;
Std::cout << m_b << Std::endl;
}
Private
int m_a;
int m_b;
};
void Main ()
{
CTest MyTest (2);
Mytest.show ();
}

-----------------------------------------------------------

Analysis
-----------------------------------------------------------

In the output, M_a is an indeterminate value because the M_b is 2 without being assigned the initial values.

Note that the following code
CTest (int b)
{
M_b = b;
CTest ();
}
When you call the CTest () function, you actually create an anonymous temporary CTest class object, and CTest () assigns m_a = 1 to the anonymous object, so the mytest we define is not actually assigned a value. To put it bluntly, the constructor does not do a piece of processing like a normal function, but instead creates an object and assigns an initial value to the object, so an explicit call to the constructor does not enable the assignment of values to the private member.

This example tells us that it is not possible to use one constructor to explicitly invoke another constructor in future code, which will cause uncertainty. In fact, some of the initialization code can be written in a separate init function, and then each constructor will call the initialization function on the line.

Here, by the way, ask another question for thought:

CTest *p = NULL;
void Func ()
{
p = new CTest ();
}

The code to the right shows the call CTest (), will still produce an anonymous temporary object A, and then assign the anonymous temporary object A's address to the pointer p? If this is the case, will the temporary object A be refactored after the Func function is out? That pointer P is not for the wild pointer? Can you explain the problem?

A: The result of my experiment is not to produce temporary object A, which directly assigns the resulting object pointer to P

Reference: http://ticktick.blog.51cto.com/823160/294573

Source: http://www.cnblogs.com/xkfz007/archive/2012/05/11/2496447.html

In-C + + constructor description and explicit call constructor

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.