C++ Learning Notes – 02

★ The Big Three Functions: Copy Constructor, Copy Assignment Operator, Destructor

◇ String Class

#ifndef __MYSTRING__
#define __MYSTRING__

class String
{
    
}

String::function(...) ...
Global-function(...) ...

#endif
C++ Learning Notes - 02

Copy s1 to s3 (where s3 appears for the first time), and copy s2 to s3 (where s3 has already appeared);

◇ The Big Three, Three Special Functions

Since characters are dynamically changing, using pointers is the most reasonable approach. Point to a location and then dynamically allocate memory size. Do not specify a size.

C++ Learning Notes - 02
char* get_c_str() const
{
    return m_data;
}
// Will not change the value of m_data, marked with const.

◇ Constructor and Destructor (ctor and dtor)

Strings will have a terminator. The length is unknown but there will be a terminator [C/C++]; one is a specified length without a terminator, which is generally in the form of an array.

inline
String::String(const char* cstr = 0)
{
    if(cstr)
    {
        m_data = new char[strlen(cstr) + 1];
        strcpy(m_data, cstr);
    }
    else{
        m_data = new char[1];
        *m_data = '\0';
    }
}

inline
String::~String()
{
    delete[] m_data;
}

C++ Learning Notes - 02

◇ Class with Pointer Members Must Have Copy Constructor and Copy Assignment Operator

C++ Learning Notes - 02

Generally, when assigning, a and b should have the same content, but they should not point to the same memory. If a changes, b will change as well, meaning they actually point to the same memory, and b’s original memory will have a leak issue.

◇ Copy Constructor (copy ctor)

inline
String::String(const String& str)   // The incoming str will not be modified, so use const
{
    m_data = new char[strlen(str.m_data) + 1];  // Create space to store the original
    strcpy(m_data, str.m_data);  // Copy the original one by one into the new space.
}

{
    String s1("hello ");
    String s2(s1);
    s2 = s1;
}

◇ Copy Assignment Operator (copy assignment operator)

inline
String& String::operator=(const String & str)
{
    if(this == &str)
        return *this;   // Check for self-assignment
    delete[] m_data;   // this is a, str is b
    m_data = new char[strlen(str.m_data) + 1];  
    strcpy(m_data, str.m_data);
    return *this;
}

{
    String s1("hello ");
    String s2(s1);
    s2 = s1;
}

Both a and b originally have content, a = b requires releasing what a originally had. Then create space as large as b, and assign b to a.

◇ Always Check for Self Assignment in operator=

★ Heap, Stack, and Memory Management

◇ Stack

A block of memory that exists within a certain scope. When you call a function, the function itself will create a stack to store the parameters it receives and the return address.

Any variable declared within the function body uses memory from the aforementioned stack.

◇ Heap

A global memory space provided by the operating system, dynamically allocated by the program, and must be manually released.

class Complex{...};
...
{
    Complex c1(1, 2);  // c1 comes from the stack
    Complex* p = new Complex(3);  // comes from the heap
}

When the scope ends, the space on the stack naturally disappears, while the space on the heap must be manually released.

◇ Lifecycle of Static Local Objects

class Complex{...};
...
{
    static Complex c2(1, 2);
}

c2 is a static object, its lifetime persists after the scope ends, until the entire program ends.

◇ Lifecycle of Global Objects

Global objects

class Complex {...};
...
    Complex c3(1, 2);
int main()
{
    
}

c3 is a global object, its lifetime also ends only after the entire program ends, and can be considered a static object whose scope is the entire program.

◇ Lifecycle of Heap Objects

class Complex{...};
...
{
    
}

◇ new: Allocate Memory First, Then Call Constructor

Complex* pc = new Complex(1, 2);

C++ Learning Notes - 02

◇ delete: Call Destructor First, Then Release Memory

◇ Memory Blocks Allocated Dynamically in VC

C++ Learning Notes - 02The gray area is in debug mode

◇ Dynamically Allocated Arrays

Complex* p = new Complex[3]; // Create three complex numbers, forming an array String* p = new String[3];

C++ Learning Notes - 02C++ Learning Notes - 02

◇ Array New Must Be Paired with Array Delete

C++ Learning Notes - 02

★ Review of the Implementation Process of the String Class

class String
{
public:
    String(const char* cstr = 0);  // Constructor, initial value assignment
    String(const String& str);   // For functions, values change, so no need for const, but for single variables, they are unchanged, so const is needed.
    String& operator = (const String& str);
    ~String();
    char* get_c_str() {return m_data;}
    
private:
    char* m_data;
}

Consider what kind of data is needed, the size of the data (generally, the length of the string is unknown, so use pointers and dynamically allocate memory later), a pointer is four bytes

Consider which functions need to be exposed for external calls

Specific implementation: place it outside the body

◇ Constructor and Destructor

◇ Copy Constructor (copy ctor) String::String(const String& str)
{
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data, str.m_data);   // Constructor does not need a return type
}

◇ Copy Assignment Operator (copy assignment operator – is a member function)

From source to destination, the destination already has content

String& String::operator=(const String& str)  // Member function has a return type
{
    if(this == &str)
        return *this;
    delete[] m_data;
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data, str.m_data);
    return *this;
}

Explanation of the & symbol: the object before it is a pointer, obtaining the address, while after the class it represents a reference.

Leave a Comment