Article directory
- 1. Overloading the left shift << operator
-
- 1. Left shift << operator function
- 2. Overload left shift << operator
- 2. Tips for using custom classes
-
- 1. Directly access private pointer members of a class
- 2. Allocate memory of the specified size for the pointer and initialize it to 0
- 3. Complete code example
-
- 1. String.h class header file
- 2. String.cpp class implementation
- 3. Test.cpp test class
1. Overload left shift << operator
1. Left shift << operator function
For left shift operator overloading, please refer to [C++] Operator Overloading ⑧ (Left shift operator overloading | Friend function/member function to implement operator overloading | Class objects use left shift operator) Blog;
The left shift operator is used in the cout << s1 << endl
statement to output the s1 object to the cout standard output stream. This is
2. Overload left shift << operator
Use global function to implement left shift operator << overload:
- First, write the function name,
cout << s1
overloads the left shift operator, The function name rule is " operate " Follow the operator to be overloaded, the function name isoperate<<
;
operate<<
- Then, Write the function parameters according to the operands, Parameters are generally references to objects; < /font>
cout << s1
The left operand is ostream cout standard output stream, and the parameter is a reference type;cout << s1
The right operand is a String s class object, and the parameter is a reference type;
operator<<(ostream & amp; out, String & amp; s)
- Then, Perfect the return value according to the business, The return value can be a reference/pointer/element; return void here That's it; returns ostream & amp; reference type to support chain calls cout << s1 << endl;
ostream & amp; operator<<(ostream & amp; out, String & amp; s)
- Finally, implement the function body, write specific operator operation business logic;
// Implement String left shift operator overloading in global function //Return ostream & reference type to support chain calls cout << s1 << endl; ostream & amp; operator<<(ostream & amp; out, String & amp; s) { cout << "Call overload left shift << operator function ostream & amp; operator<<(ostream & amp; out, String & amp; s)" << endl; // Output the data pointed to by the m_p pointer of the String object to the out output stream in the function body out << s.m_p << endl; // The return value also needs to be used as an lvalue return out; }
At the same time, the above function must be declared as a friend function of the String class in the String class;
class String {<!-- --> // Use global function to implement left shift operator << overloading // Declare the global function as a friend function of String friend ostream & amp; operator<<(ostream & amp; out, String & amp; s); }
2. Tips for using custom classes
1. Directly access private pointer members of the class
During development, a class class was customized, which defined member variables of pointer type;
Generally, member variables must be declared private;
If you want to use private pointer variables directly,
Private members can be obtained through public functions;
class String {<!-- --> public: // Get private member char* m_p char*str() {<!-- --> return this->m_p; } // Get private member int m_len intlen() {<!-- --> return this->m_len; } private: // String length, excluding '\0' //Memory space size = string length + 1 int m_len; //String pointer, pointing to the string in the heap memory char* m_p; };
2. Allocate the specified size memory for the pointer and initialize it to 0
In the parameterized constructor, a parameter of type int is received, which represents the size of the string;
If the parameter is 0, an empty string is created. The size of the memory space pointed to by the pointer is 1, and only one \0’ character is stored, indicating the end of the string;
If the parameter is greater than 0, allocate a memory space of this size + 1 for the string pointer, and then assign this memory space to 0;
Code example:
//Constructor with parameters, receives int type value, indicating the size of the string String::String(int len) {<!-- --> if (len == 0) {<!-- --> //Construct an empty string by default, the length of the string is 0 // However, the size of the memory space pointed to by the string pointer is 1, and the content is '\0' this->m_len = 0; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Copy the empty string to the memory pointed to by m_p strcpy(this->m_p, ""); } else {<!-- --> // Get the length of the incoming string // However, the size of the memory space pointed to by the string pointer needs + 1, and the content is '\0' this->m_len = len; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Set the memory space to 0 content memset(this->m_p, 0, this->m_len); } };
3. Complete code example
1. String.h class header file
#pragma once #include "iostream" using namespace std; class String {<!-- --> public: //Default parameterless constructor String(); // Constructor with parameters, receives a char* type string pointer String(const char* p); // Constructor with parameters, receiving int type value, indicating the size of the string String(int len); //Copy constructor, use String object to initialize object value String(const String & s); // destructor ~String(); public: // Overload the equal sign = operator, when the right operand is a String object String & amp; operator=(const String & amp; s); // Overload the equal sign = operator, when the right operand is a string constant value String & amp; operator=(const char* p); // Overload the array subscript [] operator char & amp; operator[](int i); // Use global function to implement left shift operator << overloading // Declare the global function as a friend function of String friend ostream & amp; operator<<(ostream & amp; out, String & amp; s); public: // Get private member char* m_p char* str(); // Get private member int m_len int len(); private: // String length, excluding '\0' //Memory space size = string length + 1 int m_len; //String pointer, pointing to the string in the heap memory char* m_p; };
2. String.cpp class implementation
//Use strcpy function to report an error // error C4996: 'strcpy': This function or variable may be unsafe. // Consider using strcpy_s instead. // To disable deprecation, use _CRT_SECURE_NO_WARNINGS. // See online help for details. #define _CRT_SECURE_NO_WARNINGS #include "String.h" //Default parameterless constructor String::String() { //Construct an empty string by default, the length of the string is 0 // However, the size of the memory space pointed to by the string pointer is 1, and the content is '\0' m_len = 0; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc m_p = new char[m_len + 1]; //Copy the empty string to the memory pointed to by m_p strcpy(m_p, ""); cout << "Call the parameterless constructor" << endl; } // Constructor with parameters, receives a char* type string pointer String::String(const char* p) { if (p == NULL) { //Construct an empty string by default, the length of the string is 0 // However, the size of the memory space pointed to by the string pointer is 1, and the content is '\0' this->m_len = 0; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Copy the empty string to the memory pointed to by m_p strcpy(this->m_p, ""); } else { // Get the length of the incoming string // However, the size of the memory space pointed to by the string pointer needs + 1, and the content is '\0' this->m_len = strlen(p); // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Copy the string to the memory pointed to by m_p strcpy(this->m_p, p); } cout << "Call parameterized constructor" << endl; } // Constructor with parameters, receiving int type value, indicating the size of the string String::String(int len) { if (len == 0) { //Construct an empty string by default, the length of the string is 0 // However, the size of the memory space pointed to by the string pointer is 1, and the content is '\0' this->m_len = 0; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Copy the empty string to the memory pointed to by m_p strcpy(this->m_p, ""); } else { // Get the length of the incoming string // However, the size of the memory space pointed to by the string pointer needs + 1, and the content is '\0' this->m_len = len; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Set the memory space to 0 content memset(this->m_p, 0, this->m_len); } }; //Copy constructor, use String object to initialize object value String::String(const String & s) { //Copy string length // Note: The size of the memory space pointed to by the string pointer needs to be + 1, and the content is '\0' this->m_len = s.m_len; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Copy the string to the memory pointed to by m_p strcpy(this->m_p, s.m_p); cout << "Call copy constructor" << endl; } // destructor String::~String() { if (this->m_p != NULL) { //Memory previously allocated using new // To release memory, you need to use delete //Memory allocated using malloc needs to be released using free delete[] this->m_p; // Set the pointer to null to avoid wild pointers. this->m_p = NULL; //Set the string length to 0 this->m_len = 0; } } // Overload the equal sign = operator, when the right operand is a String object String & amp; String::operator=(const String & amp; s) { // First process the memory allocated by this object if (this->m_p != NULL) { //Memory previously allocated using new // To release memory, you need to use delete //Memory allocated using malloc needs to be released using free delete[] this->m_p; // Set the pointer to null to avoid wild pointers. this->m_p = NULL; //Set the string length to 0 this->m_len = 0; } //Copy string length // Note: The size of the memory space pointed to by the string pointer needs to be + 1, and the content is '\0' this->m_len = s.m_len; // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Copy the string to the memory pointed to by m_p strcpy(this->m_p, s.m_p); cout << "Call the overloaded equal sign = operator function String & amp; String::operator=(const String & amp; s)" << endl; return *this; } // Overload the equal sign = operator, when the right operand is a string constant value String & String::operator=(const char* p) { // First process the memory allocated by this object if (this->m_p != NULL) { //Memory previously allocated using new // To release memory, you need to use delete //Memory allocated using malloc needs to be released using free delete[] this->m_p; // Set the pointer to null to avoid wild pointers. this->m_p = NULL; //Set the string length to 0 this->m_len = 0; } //Copy string length // Note: The size of the memory space pointed to by the string pointer needs to be + 1, and the content is '\0' this->m_len = strlen(p); // Use the new keyword to allocate memory for the char* m_p; pointer // For basic data types new is equivalent to malloc this->m_p = new char[this->m_len + 1]; //Copy the string to the memory pointed to by m_p strcpy(this->m_p, p); cout << "Call the overloaded equal sign = operator function String & amp; String::operator=(const char* p)" << endl; return *this; } // Overload the array subscript [] operator char & String::operator[](int i) { cout << "Call overloaded subscript [] operator function char & amp; String::operator[](int i)" << endl; // Directly return the corresponding i index character return this->m_p[i]; } // Get private member char* m_p char* String::str() { return this->m_p; } // Get private member int m_len int String::len() { return this->m_len; } // Implement String left shift operator overloading in global function //Return ostream & reference type to support chain calls cout << s1 << endl; ostream & amp; operator<<(ostream & amp; out, String & amp; s) { cout << "Call overload left shift << operator function ostream & amp; operator<<(ostream & amp; out, String & amp; s)" << endl; // Output the data pointed to by the m_p pointer of the String object to the out output stream in the function body out << s.m_p << endl; // The return value also needs to be used as an lvalue return out; }
3. Test.cpp test class
#include "iostream" using namespace std; //Import custom String class #include "String.h" int main() {<!-- --> //Call the parameterless constructor String s1; // Call the parameterized constructor String s2("Tom"); // Call the copy constructor String s3 = s2; //Call the overloaded equal sign operator function, the right operand is a String object s1 = s2; //Call the overloaded equal sign operator function, the right operand is a string constant value, char* pointer type s3 = "Jerry"; // Call the overloaded subscript operator function char c = s3[3]; // Call the overloaded left shift operator function cout << s3 << endl; //The console pauses, press any key to continue execution backwards system("pause"); return 0; }