C + + smart pointer

Posted by ibanez270dx on Fri, 14 Jan 2022 10:48:02 +0100

  1. Smart pointer

  • Smart pointer is essentially a template class. Generally, the object of this class is used instead of pointer
  • The smart pointer is reflected in the memory release problem. Using the smart pointer to manage the new object will no longer require manual delete
  • shared_ptr
  1. get() function: a reference to a pointer that returns data
  2. use_count() function: returns the number of smart pointer objects of the management object
  3. swap(): exchange management objects
  4. reset(): resets the management object
  5. #include<iostream>
    #include<memory>
    #include<string>
    #include<cstdio>
    using namespace std;
    class Rat {
    public:
    	~Rat()
    	{
    		cout << "Destructor" << endl;
    	}
    	void print()
    	{
    		
    	}
    protected:
    	
    };
    void printData(shared_ptr<Rat>pRat)
    {
    	cout << "call printData Function:" << endl;
    	cout << "Number of pointers to managed objects:" << pRat.use_count() << endl;
    
    }
    void FreeFile(FILE* file)
    {
    	free(file);
    }
    int main() {
    	//Basic Usage 
    	//new int(11) request memory and initialize
    	//Do initialization
    	shared_ptr<int>pInt(new int(1));
    	//Access data
    	cout << *pInt << endl;
    	//shared_ ptr<int>p=new int(2); error
    	//Custom type
    	shared_ptr<Rat>rat(new Rat);
    	rat->print();
    	//Member get() function
    	int* pData = pInt.get();
    	//user_count() function
    	shared_ptr<int>ptr(new int(1));
    	cout <<"Number of pointers to managed objects:"<< ptr.use_count() << endl;
    	shared_ptr<int>bptr(ptr);
    	cout << "Number of pointers to managed objects:" << ptr.use_count() << endl;
    	cout << "Number of pointers to managed objects:" << bptr.use_count() << endl;
    	shared_ptr<int>cptr=bptr;
    	cout << "Number of pointers to managed objects:" << cptr.use_count() << endl;
    	//swap() function and reset()
    	shared_ptr<int>a(new int('a'));
    	shared_ptr<int>b(new int('b'));
    	a.swap(b);
    	cout << "a: " << *a << "  " << " b: " << *b << endl;
    	cout << "Number of pointers to managed objects:" << a.use_count() << endl;
    	b.reset(new int('c'));
    	cout << "b: " << *b << endl;
    	{
    		shared_ptr<Rat>prat(new Rat);
    		cout << "........." << endl;
    		cout << "Number of pointers to managed objects:" << prat.use_count() << endl;
    		printData(prat);
    	}
    	//Writing with deletion
    	//Eraser: understood as the process of manually writing to free memory
    	{
    		cout << "Normal writing:" << endl;
    		shared_ptr<Rat>J(new Rat, [](Rat* p) {delete p; });
    	}
    	shared_ptr<FILE>pf(fopen("1.txt", "w"),FreeFile);
    	return 0;
    }

  • weak_ptr
  1. Weak reference pointer, no cumulative count
  2. weak_ptr can only pass through shared_ptr or weak_ptr to construct
  3. You cannot use * to get the value. You can only use - > to get the value
    #include<iostream>
    #include<memory>
    using namespace std;
    class Union {
    public:
    	void print() {
    		cout << "call" << endl;
    	}
    	~Union() { cout << "Destructor" << endl; }
    protected:
    
    };
    class B;
    class A {
    public:
    	A() { cout << "A" << endl; }
    	~A() { cout << "~A" << endl; }
    	weak_ptr<B>b;
    protected:
    
    };
    class B{
    public:
    	B() { cout << "B" << endl; }
    	~B() { cout << "~B" << endl; }
    	weak_ptr<A>a;
    protected:
    
    };
    void test() {
    	shared_ptr<A>Aobject(new A);
    	shared_ptr<B>Bobject(new B);
    	Aobject->b = Bobject;
    	Bobject->a = Aobject;
    	cout << endl;
    }
    int main() {
    	shared_ptr<Union>pa(new Union);
    	shared_ptr<Union>pb = pa;
    	cout << "Count:" << pb.use_count() << endl;
    	weak_ptr<Union>pc(pa);
    	cout << "Count:" << pb.use_count() << endl;
    	//(*pc).print();weak_ptr does not have such access
    	pc.lock().get()->print();
    	pc.lock()->print();
    	test();
    	//make_shared manages user-defined types, and the number of parameters is determined by the constructor
    	shared_ptr<int>Pmake = make_shared<int>(12);
    	cout << *Pmake<< endl;
    	int* pp = Pmake.get();
    	//delete pp; Manual deconstruction can cause deconstruction problems
    	return 0;
    }

  • unique_ptr
  1. Copy and assignment prohibited, exclusive
  2. Unique at any time_ PTR operation management object, there is always only one valid object
  3. Ownership can be transferred through the move function
  4. The reset function is combined with the release function to transfer ownership
    #include<iostream>
    #include<memory>
    #include<string>
    using namespace std;
    class Mars {
    public:
    	Mars(){}
    	Mars(int num):num(num){}
    	 int getNum() { return num; }
    	~Mars() { cout << "Mars:" << num << endl; }
    protected:
    	 int num=1;
    };
    class deleteMars {
    
    public:
    	void operator()(Mars* pMars)
    	{
    		delete []pMars;
    		cout << "Release successful" << endl;
    	}
    };
    int main() {
    	unique_ptr<Mars>pMars(new Mars(111));
    	//unique_ ptr<Mars>p1(pMars); Error, copy deleted
    	unique_ptr<Mars>p2 ;
    	//p2=pMars; error
    	cout << "Mars num: " << pMars->getNum() << endl;
    	cout << "Mars num: " << pMars.get()->getNum() << endl;
    	//move transfer of ownership
    	p2 = move(pMars);//pMars no longer manages objects
    	cout << "Mars num: " << p2->getNum() << endl;
    	unique_ptr<Mars>p3(move(p2));
    	//Can be reset
    	pMars.reset(new Mars(1));
    	cout << "Mars num: " << pMars->getNum() << endl;
    	unique_ptr<Mars>p4;
    	p4.reset(p3.release());
    	cout << p4->getNum() << endl;
    	//Delete device
    	{
    		unique_ptr<Mars,deleteMars>pArray(new Mars[4]);
    		unique_ptr<Mars, void(*)(Mars*)>pp(new Mars[3],
    			[](Mars* mars) {delete[]mars; });
    	}
    	return 0;
    }

C + + regular expression

  • Regular is a rule that matches (and thus captures, replaces) strings. This rule requires "pattern" and "string", and "pattern" processes "string" according to regular rules. This rule is supported by many languages, and regular rules are not supported until C++11

Metacharacter with special meaning

  • \The: \ character can change the original meaning of the character
  • ^: the ^ character indicates the head of the string, and the string is required to start with a character without occupying a bit\^ Represents a real ^ symbol.
  • The $: $character indicates the end of the string, and the string is required to end with a character without occupying a bit\$ Represents a real $symbol.
  • (): grouping. Large regular contains small regular. You can change the default priority. In the pattern, you can use \ 1 to represent the first set of captured things.
  • \b: Indicates the boundary of the string (head / tail / space left / space right). Character \ B requires characters to the left of the boundary and character \ B requires characters to the right of the boundary.
  • .: represents any character except \ n. \ \ Represents a real Symbol.
  • |One of: a|b | a or b
  • [abc]: any one of abc
  • \[^ abc]: other than abc
  • \[a-z]: any lowercase letter
  • \[^ a-z]: except lowercase letters
  • \w: Any alphanumeric underscore, equivalent to [(0-9)(a-z)(A-Z)()]
  • \W: Other than alphanumeric underscores, equivalent to []
  • \d: Any number
  • \D: Other than numbers
  • \s: White space (space, tab, page feed)
  • Quantifier metacharacter

  • \*: character * requires characters to appear 0 to more than once {0,}
  • +: character + requires characters to appear 1 to more than once (\ w) {1,}
  • ?: Character? Characters are required to appear 0 or 1 times {0,1}
  • {n} : character {n} requires characters to appear n times
  • {n,}: character {n,} requires character to appear n to more than once {0,}
  • {n,m}: the character {n,m} requires the character to appear n to m times
  • Therefore, metacharacters containing ` \ 'should be written as`\`

Expression of check number

  • Number: ^ [0 - 9] *$
  • N-bit number: ^ \ D {n}$
  • At least n digits: ^ \ D {n,}$
  • m - n digits: ^ \ D {m, n}$
  • Numbers starting with zero and non-zero: ^ (0 | \ [1 - 9] [0 - 9] *)$
  • Non zero digits with up to two decimal places: ^ (\ [1 - 9] [0 - 9] *) + (. [0 - 9] {1,2})$
  • Positive or negative numbers with 1 - 2 decimal places: ^ (\ -)? \d + (\.\d{ 1,2 }) ? $
  • Positive, negative, and decimal numbers: ^ (\ - | \ +)? \d + (\.\d + ) ? $
  • Positive real number with two decimal places: ^ [0 - 9] + (. [0 - 9] {2})$
  • Positive real numbers with 1 ~ 3 decimal places: ^ [0 - 9] + (. [0 - 9] {1,3})$
  • Non zero positive integer: ^ [1 - 9]\d * $or ^ (\ [1 - 9] [0 - 9] *) {1, 3} $or ^ \ +\ [1 - 9][0 - 9] * $
  • Non zero negative integer: ^ \ - \ [1 - 9] [] 0 - 9 "* $or ^ - [1-9]\d*$
  • Nonnegative integer: ^ \ D + $or ^ [1 - 9]\d * | 0$
  • Non positive integer: ^ - [1 - 9]\d * | 0 $or ^ (- \ D +)| (0 +))$
  • Nonnegative floating point number: ^ \ d + (\.\d +)$ Or ^ [1 - 9] \ d * \ \d * | 0\. \d * [1 - 9]\d * | 0 ? \. 0 + | 0$
  • Non positive floating point number: ^ (- \ D + (\. \ D +)?)| (0 + (\.0 + ) ? ))$ Or ^ (- ([1 - 9] \ d * \. \ d * | 0 \. \ d * [1 - 9] \ d *) | 0? \ 0 + | 0$
  • Positive floating point number: ^ [1 - 9] \ d * \ \d * | 0\. \D * [1 - 9] \ d * $or ^ (([0 - 9] + \. [0 - 9] * \ [1 - 9] [0 - 9] *) | ([0 - 9] * \ [1 - 9] [0 - 9] * \. [0 - 9] +) | ([0 - 9] * \ [1 - 9] [0 - 9] *)$
  • Negative floating point number: ^ - ([1 - 9]\d * \.\d * | 0\.\d * [1 - 9]\d *) $or ^ (- (([0 - 9] + \. [0 - 9] * \ [1 - 9] [0 - 9] *) | ([0 - 9] * \ [1 - 9] [0 - 9] * \. [0 - 9]) | ([0 - 9] * \ [1 - 9] *))$
  • Floating point number: ^ (-? \ D +) (\. \ D +)$ Or ^ -? ([1 - 9]\d * \.\d * | 0\.\d * [1 - 9]\d * | 0 ? \.0 + | 0)$

Expression of check character

  • Chinese characters: ^ [\ u4e00 - \ u9fa5]{0,}$
  • English and figures: ^ [A - Za - z0 - 9] + $or ^ [A - Za - z0 - 9] {4,40}$
  • All characters of length 3 - 20: ^ {3, 20}$
  • String composed of 26 English letters: ^ [A - Za - z] +$
  • String consisting of 26 uppercase English letters: ^ [A - Z] +$
  • String consisting of 26 lowercase English letters: ^ [a - z] +$
  • A string consisting of numbers and 26 English letters: ^ [A - Za - z0 - 9] +$
  • String consisting of numbers, 26 English letters or underscores: ^ \ W + $or ^ \ w {3,20}$
  • Chinese, English, numbers including underscores: ^ [\ u4E00 - \u9FA5A - Za - z0 - 9_] +$
  • Chinese, English, numbers but excluding underscores and other symbols: ^ [\ u4E00 - \u9FA5A - Za - z0 - 9] + $or ^ [\ u4E00 - \u9FA5A - Za - z0 - 9] {2,20}$
  • You can enter ^% & '; =$\ "Equal characters: \ [^% & '; =? $\ x22] + 12 it is forbidden to enter characters containing ~: \ [^ ~ \ x22]+
  • Special requirements expression

  • Email address: ^ \ w + ([-+.]\w + ) * @\w + ([-.]\w + ) * \.\w + ([-.]\w + ) * $
  • Domain name: \ [a - Za - Z0 - 9] [- A - Za - Z0 - 9] {0,62} (/. \ [a - Za - Z0 - 9] [- A - Za - Z0 - 9] {0,62}) + /?
  • InternetURL: [a - Za - Z] +: / / [^ \ S] * or ^ http: / / ([\ W -] + \.)+ [\w-]+(/[\w-./?%&=]*)?$
  • Mobile phone number: ^ (13 [0 - 9] | 14 [5 | 7] | 15 [0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9] | 18 [0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9]) \ D {8}$
  • Telephone number (0511 - 4405222, 021 - 87888822): \ D {3} - \ D {8} | \ D {4} - \ D {7}
  • ID number (15 digit, 18 digit): \d{15}, \d{18} $
  • Short ID number (number, letter X End): ([0 - 9]) {7, 18} (x X)? $ Or ^ \ D {8,18} | [0 - 9x] {8,18} | [0 - 9x] {8,18}$
  • Account number: (start with a letter, allow 5 - 16 bytes, allow alphanumeric underscores): ^ \ [a - zA - Z][a - zA - Z0 - 9_]{ 4,15 }$
  • Password: (starts with a letter, is between 6 and 18 in length, and can only contain letters, numbers and underscores): ^ [a - Za - Z] \ w {5,17}$
  • Strong password (must contain a combination of upper and lower case letters and numbers, cannot use special characters, and the length is between 8 - 10): * ^ (? =. * \ d) (? =. * [a - Z]) (? =. * [a - Z]) (? =. * [a - Z]) {8, 10}$
  • Date format: ^ \ D {4} - \ D {1,2} - \ D {1,2}
  • 12 months of a year (01-09 and 1-12): ^ (0? [1 - 9] | 1 [0 - 2])$
  • 31 days of a month (01 ~ 09 and 1 ~ 31): ^ ((0? [1 - 9]) | (1 | 2) [0 - 9]) | 30 | 31)$
  • xml file: ^ ([a - Za - Z] + -?)+ [a - zA - Z0 - 9] + \.\ [x | X]\[m | M][l | L]$
  • Regular expression for Chinese characters: [\ u4e00 - \u9fa5]
  • Double byte characters: \ [^ \ x00 - \xff] (including Chinese characters, which can be used to calculate the length of string (a double byte character length is 2, ASCII character length is 1))
  • Regular expression for blank lines: \ n \ s * \ R (can be used to delete blank lines)
  • Regular expression for HTML tag: < (\ s *?) [^ > ] *>.* ? < / \ 1> | <.* ? / > (complex nested tags are still powerless)
  • Regular expressions for leading and trailing white space characters: ^ \ s * | \s * $or (^ \ s * | (\ s * $) (can be used to delete white space characters at the beginning and end of lines (including spaces, tabs, page breaks, etc.))
  • Tencent QQ No.: \ [1 - 9] [0 - 9] {4,} (Tencent QQ No. starts from 10000)
  • China Postal Code: [1 - 9] \ D {5} (?)! (China postal code is 6 digits)
  • IP address: \ D + \ \d + \. \d + \. \D + (useful when extracting IP addresses)
  • IP address: (?: (?: 25 [0 - 5] | 2 [0 - 4] \ \ D | [01]? \ \ D? \ \ d) \ \.) { 3 }(? : 25[0 - 5] | 2[0 - 4]\d | [01] ? \d ? \d))
#include<iostream>
#include<string>
#include<regex>
using namespace std;
//Match bool regex_match(string str,regex reg)
//Matching return: true, false if not satisfied
void testRegex_match()
{
#if 0
	regex reg("^\\w + ([-+.]\\w + ) * @\\w + ([-.]\\w + ) * \\.\\w + ([-.]\\w + ) * $");
	string email;
	while (1)
	{
		cout << "Please enter email address:";
		cin >> email;
		bool result = regex_match(email, reg);
		if (result)
		{
			cout << "Correct input" << endl;
			break;
		}
		else {
			cout << "Please enter the correct format" << endl;
		}		
	}
#endif
	string str = "ILoveYou1314";
	regex reg("[a-z0-9]+");//Lowercase letters or numbers
	if (regex_match(str, reg)) {
		cout << "Correct input" << endl;
	}
	else
		cout << "error" << endl;
	//regex_constants::icase can ignore case
	regex reg1("[a-z0-9]+", regex_constants::icase);
	if (regex_match(str, reg1)) {
		cout << "Correct input" << endl;
	}
	else
		cout << "error" << endl;
	//Strings can also act as regular rules
	regex reg2("ILoveyou1314",regex_constants::icase);
	if (regex_match(str, reg2)) {
		cout << "Correct input" << endl;
	}
	else
		cout << "error" << endl;
}
//Regular replace regex_replace(string str,regex reg)
void testRegex_replace()
{
	string str = "ILove1234You123";
	regex reg("\\d+");
	cout << "str:" << regex_replace(str, reg, "woaini") << endl;
	cout << str << endl;
	//How to control substitution
	//Value replaces the first regex occurrence_ constants::format_ first_ only
	cout << " first_only:" << regex_replace(str, reg, "woaini"
		, regex_constants::format_first_only)<<endl;
	//Do not copy
	cout << "no_copy:" << regex_replace(str, reg, "woaini",
		regex_constants::format_no_copy)<<endl;
    //Default mode
	cout << "default:" << regex_replace(str, reg, "woaini",
		regex_constants::format_default)<<endl;
	//sed
	cout << "sed:" << regex_replace(str, reg, "woaini",
		regex_constants::format_sed) << endl;
}
//Intercept processing string
void testRegex_search()
{
	string str = "ILoveYou1314hhhhh1234";
	smatch result;
	bool flag = regex_search(str, result, regex("\\d+"));
	if (flag)
	{
		cout << result.size() << endl;
	}
	for (int i = 0; i < result.size(); i++)
	{
		cout << result.str() << endl;
	}
	cout << "pre:" << result.prefix() << endl;
	cout << "suf:" << result.suffix() << endl;
	//After matching: result Suffix can be intercepted continuously as a cyclic condition
	//sregex_iterator
	regex rule("\\d+");
	sregex_iterator pos(str.begin(), str.end(), rule);
	sregex_iterator end;
	while (pos != end)
	{
		cout << pos->str() << endl;
		pos++;
	}
	//Disassemble string
	//sregex_token_iterator(iterator begin(),iterator end(),regex reg,int flag)
	//Flag: 0 all matches, - 1: all mismatches
	regex regexRule("\\d+");
	sregex_token_iterator Begin(str.begin(), str.end(), regexRule, 0);
	sregex_token_iterator End;
	while (Begin!= End)
	{
		cout << Begin->str() << endl;
		Begin++;
	}
}
int main() {
	testRegex_match();
	testRegex_replace();
	testRegex_search();
	return 0;
}

Topics: C++ Back-end