C + + Learning Notes 2

Posted by mona02 on Wed, 12 Jan 2022 06:13:26 +0100

C + + Learning Notes 2

object-oriented

Class string with pointer

How to save data?

It's good to use pointers. You can't save them one by one

Copy construction, copy replication

The parameters accepted by the constructor are the object (Reference) of its own class, which is constructed for copy.

=Overloaded, the parameter is the object of its own class, which is copied.

String(const String& str);                    
String& operator=(const String& str); 

inline
String::String(const String& str)
{
   m_data = new char[ strlen(str.m_data) + 1 ];
   strcpy(m_data, str.m_data);
}

inline
String& String::operator=(const String& str)
{
   if (this == &str)
      return *this;//To detect self assignment, be sure to

   delete[] m_data;//Empty first
   m_data = new char[ strlen(str.m_data) + 1 ];//Allocate the same space
   strcpy(m_data, str.m_data);//Copy
   return *this;
}

String s1("hello");
String s2(s1);
String s2=s1;//It has the same meaning as the previous line, and it's similar to the function implementation

As long as you write a class with a pointer, you must complete these two functions. For the class complex without pointer, it is the same if it is not written. The compiler will faithfully copy the bit completely, which is very good. However, pointers cannot be copied and space should be reallocated.

Shallow copy is pure bit copy, resulting in memory leakage and alias; Deep copy is to recreate and assign the content pointed by the pointer.

The constructor here is implemented externally.

Constructor

String(const char* cstr=0);

#include <cstring>
inline
String::String(const char* cstr)
{
   if (cstr) {
      m_data = new char[strlen(cstr)+1];
      strcpy(m_data, cstr);
   }
   else {   //Initial value not specified
      m_data = new char[1];
      *m_data = '\0';
   }
}

String* p=new String("hello")

Destructor

The writing method is similar to the constructor, with the same name as the class, and there is a ~

~String();


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

When the object of this class dies and leaves the scope, it will be called (automatically).

For classes with pointers, destructors should be used to process dynamically allocated space (manually).

Objects dynamically allocated with pointers should also be delete d manually.

Output function

To write a global function,

#include <iostream>
using namespace std;

ostream& operator<<(ostream& os, const String& str)
{
   os << str.get_c_str();
   return os;
}

char* get_c_str() const {return m_data;}//Write to class

Heap heap and Stack stack, and new keyword

Memory

Stack is a memory space in the scope of a function, which is used to store parameters, return addresses, etc.

Heap is a global memory space provided by the operating system, which can be dynamically allocated by the program to obtain a certain size.

Complex c1(1,2);
Complex* c2=new Complex(2,3);

The contents of the stack will be released after the function ends (leaving the scope). The destructor is called. It is also called auto object because it will be released automatically.

If it is a static object, it will not be released until the end of the whole program.

If it is a global object, it is a bit like static. It will be released only after the program ends.

The contents of the heap must be released manually. A new corresponds to a delete, and its life ends after delete. If it is not released, the memory will be leaked. The severity is that when the scope ends, the life of the pointer ends. There is no way to use the pointer outside the scope, and the memory of this block will lose control.

new and delete

new is to allocate memory first and then call the constructor ctor. It can be divided into the following steps:

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

Complex* pc;
void mem=operator new(sizeof(Complex));//operator new is actually a function with a special name. The next layer is malloc.
pc=static_cast<Complex*>(mem);//Pointer type conversion
pc->Complex::Complex(1,2);//Constructor

The constructor is a member function and is now called by a pointer. Therefore, it is equivalent to that the pointer is this in the constructor and points to the starting point of memory space. Then the constructor is called to copy.

delete is to call the dtor of the destructor first, and then release the memory.

String* ps = new String("Hello");
delete ps;


String::~String(ps);//Release the dynamically allocated space in the string
operator delete(ps);//The next floor is free

Memory block size

The memory space allocated by vc must be a multiple of 16B.

Under debug. It contains a lot of debugging information and cookie s (used to record the length and allocation status, which are provided to malloc and free). There may also be padding with an integer multiple of 16B.

Under release, there is no debugging information, and everything else is the same.

New and delete with brackets (array new / delete)

Match each other, or you will make mistakes. It is written as follows:

m_data = new char[strlen(cstr)+1];

delete[] m_data;

In the dynamically allocated array, there will be an integer record array capacity in front of the data. (VC) specific questions are as follows:

There is no problem deleting the entire array, because the case is in the cookie; However, except for the 0th element, the destructor of the following elements is not called, which causes a memory leak. (of course, because the variables of the following classes have pointers)

Topics: Cpp