C ++ Primer learning note _ 29 _ operator Overloading and conversion (4) -- Conversion constructor and type conversion operator induction, operator new and operator delete implement a simple memory leakage tracker, operator type conversion

Source: Internet
Author: User

C ++ Primer learning note _ 29 _ operator Overloading and conversion (4) -- Conversion constructor and type conversion operator induction, operator new and operator delete implement a simple memory leakage tracker, operator type conversion
C ++ Primer learning note _ 29 _ operator Overloading and conversion (4) -- Conversion constructor and type conversion operator induction, operator new and operator delete implement a simple memory leakage Tracker

1. The conversion constructor can call with a single real parameter to define an implicit conversion from the form parameter type to the type. As follows:

Class Integral {public: Integral (int = 0); // conversion constructor private: int real;}; Integral A = 1; // call the conversion constructor to convert 1 to an object of the Integral class

The conversion constructor must meet one of the following conditions:
(1) constructor with only one int type parameter is provided in the definition and implementation of the Integral class;
(2) An int type parameter is provided in the definition and implementation of the Integral class, and all other parameters have default constructor values;
(3) Although the definition and implementation of the Integral class does not contain int type parameters, it contains a non-int type parameter, such as float type. In addition, no other parameters or other parameters have default values, int type parameters can be implicitly converted to float type parameters.
You can disable implicit conversion by declaring the constructor as explicit.


2. the type conversion operator can convert a specified type of data to a class object through the conversion constructor. However, you cannot convert a class object to another type of data. For example, you cannot convert an Integral class object to an int type. Therefore, C ++ provides a function called the type conversion operator to solve this conversion problem. When a type conversion function is used, the object of a class is converted to another type of data. In the class, the general format of the type conversion function is defined:
Class Integral {public: Integral (int = 0); operator int (); // type conversion operator private: int real ;}; Integral A = 1; // call the conversion constructor to convert 1 to the integer Class Object int I = A; // call the type conversion operator function to convert the Class A object to the int type

Define the type conversion function,
Note the following points: (1) the conversion function must be a member function, not a friend form;
(2) The conversion function cannot specify the return type, but the return statement must be used in the function to return a variable of the target type by passing the value;
(3) The conversion function cannot have parameters.
For example, the integer type conversion function to int is:
operator int(){    return real;}
The function name of this type conversion function is "operator int". The target type to be converted is int, and the function body is "return real".

[Example]
In which of the following circumstances cannot B be implicitly converted to ()?
A. class B: public {}
B. class A: public B {}
C. class B {operator ();}
D. class A {A (const B &);}
Answer: B. Because the subclass contains the parent class, the subclass can be converted to the parent class, but on the contrary, the parent class does not have any additional defined part of the subclass, so it cannot be converted to the subclass.

Conclusion: for non-C ++ built-in types A and B, B can be implicitly converted to A in the following situations.
(1) Public B inherits from A and can be indirectly inherited.
class B: public A {};

(2) B has a type conversion function.
class B{    operator A();};
If "A a; B B;" exists, "a = B;" is valid.

(3) A implements A constructor whose non-explicit it parameter is B (other parameters with default values may be available)
class A{    A (const B&);};
If "A a; B B;" exists, "a = B;" is valid.


Iii. Heavy Load of operator new and operator delete

In fact, we cannot redefine the new and delete expressions. The global functions operator new and operator delete can be overloaded.

The new execution process is: first, call the standard library function named operator new to allocate enough untyped memory to save an object of the specified type. Next, run a constructor of this type to construct an object with the specified initialization type. Finally, a pointer to the newly allocated and constructed object is returned.

The delete execution process is: first, run the appropriate destructor on the object pointed to by sp; then, call the standard function named operator delete to release the memory used by the object.

The above opeartor new and operator delete can be overloaded.

[Example 1]

What is the output result of the following code?

#include <iostream>using namespace std;class X{public:    X() {cout << "constructor" << endl;}    static void* operator new(size_t size)    {        cout << "new" << endl;        return ::operator new(size);    }    static void operator delete(void* point)    {        cout << "delete" << endl;        ::operator delete(point);    }    ~X() {cout << "destructor" << endl;}};int main(){    X* p = new X();    delete p;    return 0;}

Answer:

New
Constructor
Destructor
Delete


New operator features:

(1) call operator new to allocate enough space and call constructors of related objects;

(2) cannot be overloaded

Operator new features:

(1) allocate only the required space and call the constructor of the object;

(2) It can be reloaded.

(3) During overload, the return type must be declared as void *;

(4) During heavy load, the first parameter type must be the size (in bytes) required for space allocation for the expression, and the type is size_t;

(5) You can include other parameters when reload is performed.

Operator new corresponds to operator delete and malloc and free in C language, and is only responsible for allocating and releasing space. However, the space allocated by operator new must be released using operator delete, but not free, because they have different registration methods for memory usage. The same is true.


[Example 2]
# Include <iostream> # include <stdlib. h> using namespace std; class Test {public: Test (int n): n _ (n) {cout <"Test (int n): n _ (n) "<endl ;}test (const Test & other) {cout <" Test (const Test & other) "<endl ;}~ Test () {cout <"~ Test () "<endl ;} /*************************************** * ***********************/void * operator new (size_t size) {cout <"void * operator new (size_t size)" <endl; void * p = malloc (size); return p;} void operator delete (void * p) // similar to the operator delete function below, priority is given to coexistence. {// match the operator new function cout <"void operator delete (void * p)" <endl; free (p);} void operator delete (void * p, size_t size ){ Cout <"void operator delete (void * p, size_t size)" <endl; free (p );} /*************************************** * *****************************/void * operator new (size_t size, const char * file, long line) {cout <"void * operator new (size_t size, const char * file, long line);" <endl; cout <file <":" <line <endl; void * p = malloc (size); return p;} void operator delete (void * p, const Char * file, long line) {cout <"void operator delete (void * p, const char * file, long line);" <endl; cout <file <":" <line <endl; free (p);} void operator delete (void * p, size_t size, const char * file, long line) {cout <"void operator delete (void * p, size_t size, const char * file, long line);" <endl; cout <file <":" <line <endl; free (p );} /******************************** **************************************** **/Void * operator new (size_t size, void * p) {cout <"void * operator new (size_t size, void * p);" <endl; return p;} void operator delete (void *, void *) {cout <"void operator delete (void *, void *);" <endl ;} /*************************************** * **********************************/int n _; }; /*************** global *********************** ********* * ************/Void * operator new (size_t size) {cout <"global void * operator new (size_t size) "<endl; void * p = malloc (size); return p;} void operator delete (void * p) {cout <" global void operator delete (void * p) "<endl; free (p );} /*************************************** * *****************************/void * operator new [] (size_t size) {cout <"global void * operator new [] (size_t size)" <end L; void * p = malloc (size); return p;} void operator delete [] (void * p) {cout <"global void operator delete [] (void * p)" <endl; free (p );} /*************************************** * *******************************/int main (void) {Test * p1 = new Test (100); // call delete p1 for new operator = operator new + constrfunction; char * str1 = new char; delete str1; char * str2 = new char [100]; delete [] str2; char chunk [10]; T Est * p2 = new (chunk) Test (200); // operator new (size_t, void * _ Where) // placement new, cout calls without memory allocation + constructor <p2-> n _ <endl; p2-> ~ Test (); // explicitly call the Destructor // Test * p3 = (Test *) chunk; Test * p3 = reinterpret_cast <Test *> (chunk ); cout <p3-> n _ <endl; # define new (_ FILE __, _ LINE __) // Test * p4 = new (_ FILE __, _ LINE _) Test (300); Test * p4 = new Test (300); delete p4; return 0 ;}
Running result:
Void * operator new (size_t size)
Test (int n): n _ (n)
~ Test ()
Void operator delete (void * p)
Global void * operator new (size_t size)
Global void operator delete (void * p)
Global void * operator new [] (size_t size)
Global void operator delete [] (void * p)
Void * operator new (size_t size, void * p );
Test (int n): n _ (n)
200
~ Test ()
200
Void * operator new (size_t size, const char * file, long line );
Test. cpp: 131
Test (int n): n _ (n)
~ Test ()
Void operator delete (void * p)

The output shows the following points:

(1) new operator allocates memory (calls operator new) + calls Constructor

(2) operator new only allocates memory and does not call constructor.

(3) placement new indicates that no memory is allocated (operator new (different from 2) is called to return the allocated memory address), and constructor is called.

(4) delete: Call the Destructor first, and then call operator delete.

(5) If the new object is an array, delete [] must be released accordingly.


[Example 3]
How can I limit the generation of stack objects? How do I limit the generation of heap objects?
Answer:
Prohibit heap objects:
The only way to generate heap objects is to use the new operation. You can disable the use of new to generate heap objects. How can I disable the new operation? Operator new is called when the new operation is executed, and operator new can be reloaded. Therefore, operator new is set to private. For symmetry, it is best to reload operator delete to private.
Stack object generation prohibited:
When creating a stack object, you do not need to call new. When creating a stack object, the top pointer of the stack is moved to the desired size of the space, then, the corresponding constructor is called directly in this space to form a stack object. When the function returns, the corresponding constructor is called to release the object, then adjust the stack top pointer to reclaim the stack memory. Therefore, the constructor and destructor are set to private, so that the system cannot call constructor and destructor. Of course, the object cannot be generated in the stack.



Refer:

C ++ primer version 4

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.