You are welcome to repost the post, but please mark the author as "nine days Yan Ling". Of course, the link to this post is better.
Do you still remember the constructor mentioned in (1? Review, this time we reload a new default constructor-that is, the constructor called when you do not give an initial value. Do you know this concept? Let's look at the example below.
Example 6.0
# Include <string>
# Include <iostream>
Using namespace STD;
Class fruit // defines a class named fruit
{
String name; // defines a name Member.
String color; // defines a color member.
Public:
Void print () // defines the print () member of an output name ()
{
Cout <color <"" <name <Endl;
}
Fruit (const string & NST, const string & CST = "green"): Name (NST), color (CST) // Constructor
{
Name + = "S ";
}
Fruit (istream & is = CIN) // new Constructor
{
Is> color> name;
}
};
Int main ()
{
Fruit Apple ("apple"); // defines a fruit object Apple
Fruit apple2;
Apple. Print ();
Apple2.print ();
Return 0;
}
I found that the default constructor I overloaded does not exist? This time, the default parameter istream & is = CIN is used. If I have learned Io, I should know that it means that the default parameter is input from a standard device (such as a keyboard ). When you run it, you will know what is going on. Now let's talk about a new content, copying constructor. What does it mean? Let's take a look at the example below.
Example 6.1:
# Include <string>
# Include <iostream>
Using namespace STD;
Class fruit // defines a class named fruit
{
String name; // defines a name Member.
String color; // defines a color member.
Public:
Void print () // defines the print () member of an output name ()
{
Cout <color <"" <name <Endl;
}
Fruit (const string & NST, const string & CST = "green"): Name (NST), color (CST) // Constructor
{
Name + = "S ";
}
Fruit (){}
};
Int main ()
{
Fruit Apple ("apple"); // defines a fruit object Apple
Fruit apple2 (Apple); // is there any problem?
Apple. Print ();
Apple2.print ();
Return 0;
}
You will find that apple2 also outputs green apples. Why? (Apple) is the same as ("apple? You may be wrong when you understand this. But when we use fruit apple2 (Apple); which constructor does it call? We have not defined a similar constructor? Compilation should fail, right? Well, the constructor called here is called a copy constructor, that is, using an object of the same type to construct the constructor of another object. However, we have not defined it here, therefore, the default replication constructor is automatically defined by the system. The effect is simply a copy. If you change the first object to apple3, you will find that apple2 cannot be defined because it calls the copy fruit object Apple constructor, instead of using the string "apple. C ++ primer defines the replication constructor as follows. I reference "only a single shape parameter, and this shape parameter is a reference to this type of object (commonly used for const modification )". Let's take a look at an interesting application of the default copy constructor synthesized by the system:
Example 6.2:
# Include <iostream>
Using namespace STD;
Class aint
{
Public:
Int aival [3];
};
Int main ()
{
Aint as = {1, 2, 3 };
Cout <as. aival [0] <as. aival [1] <as. aival [2] <Endl;
Aint BS ();
Cout <BS. aival [0] <BS. aival [1] <BS. aival [2] <Endl;
Return 0;
}
It's a simple example, but it's also interesting. We all know that there is no way to copy an array by equals. To copy an array, you can only traverse it cyclically, we have defined a class that only contains an integer array. When we use the default copy constructor synthesized by the system, we can copy the array. Note that this is a one-time copy. Haha. This also illustrates the problem, that is, when the system's default copy constructor is dealing with arrays, it will help us traverse and copy. Now we define a replication constructor. It should be noted that, in general, the replication constructor defined by the system is enough, and you want to implement different functions when you want to define it, for example, it is better to process pointer replication. The following example only shows usage. I only talk about usage without worrying about the practical significance.
Example 6.3:
# Include <string>
# Include <iostream>
Using namespace STD;
Class fruit // defines a class named fruit
{
String name; // defines a name Member.
String color; // defines a color member.
Public:
Void print () // defines the print () member of an output name ()
{
Cout <color <"" <name <Endl;
}
Fruit (const string & NST = "apple", const string & CST = "green"): Name (NST), color (CST) {}// Constructor
Fruit (Fruit & AF): Name (Af. Name), color (Af. Color) // This is our own replication constructor.
{
Name + = "S"; // make him different from the default one
}
};
Int main ()
{
Fruit apple; // defines a fruit object
Fruit apple2 (Apple); // call our own replication constructor.
Apple. Print ();
Apple2.print (); // you will find an extra 's' output'
Return 0;
}
Here you will see the role of our own replication constructor. We can intuitively see that Apple only outputs green apple, while apple2 outputs green aples, this is also a copy constructor. You can also use the initialization list. We recommend that you use the initialization list in C ++ primer. Next let's take a look. What if you want to disable replication for your class? It is very easy to let your replication constructor go to private. At this time, you can use replication for friends and members. Then you will declare a replication constructor. However, you do not define it, in C ++, it is legal to declare that a member function is not defined. However, if it is used, compilation fails. (This is also true for common functions, you can disable all replication (in fact, it is the place where everything needs to be copied to the constructor ). See the following example.
Example 6.4:
# Include <string>
# Include <iostream>
Using namespace STD;
Class fruit // defines a class named fruit
{
String name; // defines a name Member.
String color; // defines a color member.
Public:
Void print () // defines the print () member of an output name ()
{
Cout <color <"" <name <Endl;
}
Fruit (const string & NST = "apple", const string & CST = "green"): Name (NST), color (CST)
{} // Constructor
PRIVATE:
Fruit (Fruit & AF); // define it in private
};
Int main ()
{
Fruit Apple ("apple"); // defines a fruit object Apple
// Fruit apple2 (Apple); // your attempt will cause compilation failure and cannot access private Error
Apple. Print ();
Return 0;
}
After making a mistake that I haven't found for a long time, I found that when an object is defined and initialized in the form of fruit apple2 = Apple, the replication constructor is also called. For details, see the post "Be cautious! In C ++, "=" is not necessarily equal to (Value assignment ). "