[C++ Practice Road] 28. New class functions

insert image description here
Every day without dancing is a disappointment to life

foreword

This article is still new in C++11.

1. Default member functions

In the original C++ class, there are 6 default member functions:

  1. Constructor
  2. destructor
  3. copy constructor
  4. copy assignment overloading
  5. take address overload
  6. const take address overload

Last but not least are the first 4, the latter two are of little use. The default member function is that if we don't write the compiler will generate a default one.


C++11 adds two new ones: move constructor and move assignment operator overloading.

There are some points to note for move constructor and move assignment operator overloading as follows:

  • If you do not implement the move constructor yourself, and do not implement any of the destructor, copy construction, and copy assignment overloads. then the compiler will automatically generate a default move construct. The default generated move constructor will perform a member-by-member byte-by-byte copy for built-in type members. For custom type members, it needs to check whether the member implements move construction. If it is implemented, it will call move construction. If not, it will call copy construction.
  • If you do not implement the move assignment overload function yourself, and do not implement any of the destructor, copy construction, and copy assignment overloads, then the compiler will automatically generate a default move assignment. The move constructor generated by default will execute member-by-member byte-by-byte copy for
    built- type members, you need to check whether the member implements move assignment. If it is realized, call move assignment. If not, call copy assignment . (The default move assignment
    is exactly similar to the move construction above)
  • If you provide move construction or move assignment, the compiler will not automatically provide copy construction and copy assignment.

Observe the code to see:

class Person
{
    
    
public:
	Person(const char* name = "", int age = 0)
		:_name(name)
		, _age(age)
	{
    
    }
	/*Person(const Person& p)
	:_name(p._name)
	,_age(p._age)
	{}*/

	/*Person& operator=(const Person& p)
	{
		if(this != &p)
		{
			_name = p._name;
			_age = p._age;
		}
		return *this;
	}*/

	/*~Person()
	{}*/
private:
	cfy::string _name;
	int _age;
};
int main()
{
    
    
	Person s1;
	Person s2 = s1;
	Person s3 = std::move(s1);
	Person s4;
	s4 = std::move(s2);
	return 0;
}

image-20230310172112484

If either or both of the annotations are turned on:image-20230310172207520

2. Class member variable initialization

C++11 allows member variables to be given initial default values ​​when defining a class, and the default generated constructor will be initialized with these default values. We talked about this in Lei and Object Default, so I won’t go into details here.

3. The keyword default that forces the default function to be generated

If you need to write a destructor, the move construction will not be generated by default at this time, so you can use default to force the generation of the move construction:

// 以下代码在vs2013中不能体现,在vs2019下才能演示体现上面的特性。
class Person
{
    
    
public:
	Person(const char* name = "", int age = 0)
		:_name(name)
		, _age(age)
	{
    
    }
	Person(const Person& p)
		:_name(p._name)
		, _age(p._age)
	{
    
    }
	/*Person(Person&& p)
		:_name(std::forward<cfy::string>(p._name))
		, _age(p._age)
	{}*/

	//强制生成
	Person(Person&& p) = default;

	/*Person& operator=(const Person& p)
	{
		if (this != &p)
		{
			_name = p._name;
			_age = p._age;
		}
		return *this;
	}*/

	~Person()
	{
    
    }
private:
	cfy::string _name;
	int _age;
};
int main()
{
    
    
	Person s1;
	Person s2 = s1;
	Person s3 = std::move(s1);

	return 0;
}

image-20230310192750553

4. It is forbidden to generate the keyword delete of the default function

If you want to limit the generation of some default functions, in C++98, the function is set to private, and only the patch is declared, so that as long as others want to call it, an error will be reported. It is simpler in C++11, just add =delete to the function declaration, this syntax instructs the compiler not to generate a default version of the corresponding function, and the function modified by =delete is called a delete function. In terms of copy construction:

The c++98 way:

For c++98, the constructor is written out and placed privately, which can prevent external calls to copy construction, but not internally; but only declare but not implement in the class, and declare it as private can also prevent internally.

class A
{
    
    
public:
	A()
	{
    
    }
	~A(){
    
     delete[] p;}
private:
	//只声明不实现,声明为私有 C++98
	A(const A& aa);//浅拷贝
	int* p = new int[10];
};

The way of c++11: (succinct - recommended)

class A
{
    
    
public:
	A()
	{
    
    }
	~A(){
    
     delete[] p;}
	//c++11
	A(const A& aa) = delete;
private:
	int* p = new int[10];
};

C++11 directly prohibits the call of copy construction by means of delete. Therefore, delete is undoubtedly the best way.

Guess you like

Origin blog.csdn.net/NEFUT/article/details/129642760