The replication constructor also takes the sales_item class as an example,
When declaring and defining the sales_item () function, you must reload this function, sales_item (const sales_item &);
The final result is sales_item Item1; sales_item item2 (Item1); if the value assignment constructor is overloaded, the object can be directly
Copy, for example, Item1 = item2;
Declare in class, reload
Sales_item (const sales_item &);
Out-of-class definition:
Sales_item: sales_item (const sales_item & item)
{
ISBN = item. ISBN;
Units_sold = item. units_sold;
Revenue = item. revenue;
Return * this;
}
This is a replication constructor with no pointer member in the class member. If there is a pointer member, it is another matter. Copy constructor
A class is not necessary. If a data member is pointer-type, you must pay attention to its copy form. Otherwise, errors may occur.
The member data of the class is not defined if it contains the member data of the pointer type but does not define the replication constructor. If the program needs it, this will be written later. The following describes the detailed details of the replication constructor:
The replication constructor can be automatically merged by the compiler. If the default constructor is explicitly defined, the default synthesis constructor will not be called,
When a copy constructor is explicitly defined, Its Parameter type is a reference of this class type, which is often modified by const and must be referenced by this class.
Object initialization form:
String null_book = "999-99-9-999"; in this way, create a temporary object and copy the temporary object to null_book by calling the copy constructor;
String DOTS (10, '.'); initialize directly
String empty_copy = string (); copy Initialization
String empty_direct; direct Initialization
During replication initialization, the replication constructor is implicitly called, which is dangerous for some classes. In addition, operator = () is called for the first and third operators in the four examples ();
If the replication constructor is private or explicit, the above definition is not allowed.
Return Value Type
Class references are often returned, in the address-passing mode.
Replication control:
Some Classes need to completely prohibit replication. For example, the iostream class does not allow replication. To disable replication, you can only declare it, but do not define it. Or set the copy constructor as a private member function.
Most classes should define the replication constructor and default constructor. If a replication constructor is defined, the default constructor must also be defined ..
Sales_item & sales_item: Operator = (const sales_item & item)
{
ISBN = item. ISBN;
Units_sold = item. units_sold;
Revenue = item. revenue;
Return * this;
}
The copy constructor and value assignment are often used together. Of course, there is no pointer type in sales_item. If the class contains a pointer type, you must control the replication of the pointer type!
Manage class pointer members:
When designing a class with pointer members, the class designer first needs to decide that the pointer should provide declarative behavior. When copying a pointer to another pointer, the two pointers point to the same object. At this time, the two pointers direct to the same object. When a pointer is used to modify the value or even delete the value, but the other pointer pointing to the data is unknown, a hanging pointer may occur, cause memory leakage .., different replication control policies can be used to implement different behaviors for pointer members.
1. pointer members adopt regular pointer-type behaviors. Such classes have all pointer defects without special replication control.
2. The class can implement the so-called "smart pointer" behavior. Objects with multiple pointers are shared, but the class can prevent hanging pointers.
3. The class adopts a value-type behavior to manage pointer members in three different ways.
The method of 1 is a class that is not responsible anymore .......
The 2 method is to make pointers intelligent, but it is not necessary for some classes ........
The 3 method is easy to understand and can solve the problem of pointer member management in some non-complex classes with a structure ........
Class hasptr
{
Public:
Hasptr (int * P, int I): PTR (P), Val (I)
{}
// N characters are omitted here
PRIVATE:
Int * PTR;
Int val;
};
In pointer replication, if the third method is used, a new address space must be opened for the pointer variable,
Hasptr: hasptr (const hasptr & temp)
{
PTR = new int (* temp. PTR); // a new space is fully created here, not only copying the pointer, but also copying the data pointed to by the pointer.
Val = temp. Val;
};
Smart pointer
1. The reference count is used. Every time a pointer member is copied, the smart pointer class associates a counter with the object pointed to by the class. Use count to track how many objects in the class share the same pointer. Delete an object when the count is zero.
Each time a new object of the class is created, the pointer is initialized and counted to one. When an object is created as a copy of another object, copy the constructor to copy the pointer and add the corresponding Count value. When an object is assigned a value, the value assignment operator reduces the Count value of the object indicated by the left operand, and adds the Count value of the right operand to the object. Finally, when calling the destructor, The Destructor reduces the Count value. If the count is reduced to 0, the basic object is deleted. The only innovation depends on where the count is put. The counter cannot be directly placed in the hasptr object.
Class u_ptr
{
Friend class hasptr;
Int * IP address;
Size_t use;
U_ptr (int * P): IP (P), use (1 ){}
~ U_ptr () {Delete IP ;}
};
Class hasptr
{
Public:
Hasptr (int * P, int I): PTR (New u_ptr (p), Val (I ){}
Hasptr (const hasptr & orig): PTR (orig. PTR), Val (orig. Val) {++ PTR-> use ;}
Hasptr & operator = (const hasptr );
~ Hasptr () {If (-- PTR-> Use = 0) delete PTR ;}
PRIVATE:
U_ptr * PTR;
Int val;
};
Hasptr & hasptr: Operator = (const hasptr & RHs)
{
++ RHS. PTR-> use;
If (-- PTR-> Use = 0)
Delete PTR;
PTR = RHS. PTR;
Val = RHS. Val;
Return * this;
}
The above is an example of smart pointer usage.