C++ learning six

std::unique_ptr func(void)
{ unique_ptr pr(new string(“i love china”)); return pr; //Return a local object } int main(void) { unique_ptr ps = func(); return 0; }







2)unique_ptr删除器
void deleteFunc(string* pdel)
{
delete pdel;
pdel = nullptr;
cout << “8888888” << endl;
}
int main(void)
{
using ptr = void ()(string); //using定义函数指针
//typedef void (ptr)(string);
unique_ptr<string, ptr> p1(new string(“abc”), deleteFunc);
return 0;
}

Member functions can call member functions, I don’t care if they are public or private;
class A
{ public: void func(void) { cout << “00000000” << endl; func2(); //Member functions can When calling a member function, I don’t care whether it is public or private; } private: void func2(void) { cout << “0****************” << endl; } }; int main(void) { A* a = new A(); a->func(); return 0; }

















//When generating objects, there are many ways;
class A
{ public: A(int a, float b):a_(a),b_(b) { cout << "constructor" << endl; } private : int a_; float b_; }; int main(void) { A a{ 3,4.6 }; A a2(4, 5.7); A a3 = A(3, 6); A a4 = A{ 5,3.7 } ; A a2 = { 5,5.0 }; //The equal sign and braces perform implicit type conversion //The copy constructor is called A a11{ a }; A a21(a); A a31 = A( a); A a41 = A{ a }; A a41 = { a }; return 0; }























//Using one object to initialize another object is called copying;
function default parameters: default values ​​can only be placed in function declarations, unless the function has no function declaration;
once a default value appears, the parameters on the right must all specify default value;

//Implicit conversion and express
class A
{ public: A(int a) { b_ = 45.9; a_ = a; cout << "Constructor 2" << endl; } private: int a_; float b_; };










void func(A a)
{

}
int main(void)
{
//A a1 = 3; //Implicit type conversion occurred, 45 was converted to a temporary object
//A a2 = (4, 2, 1, 7, 8); //Appeared With implicit type conversion, the last parameter 8 is converted to a temporary object

func(45);//45被转换了一个临时对象,调用了构造函数
return 0;

}

A aa = {54}; //The curly brackets can be considered as an object;
the constructor corresponding to a single parameter is generally declared as explicit;
the constructor must be used to initialize the list;

Initialization and assignment are two completely different concepts, so it is better to use the constructor initialization list (more efficient);
in the constructor initialization list, do not use one member variable to assign another member variable;
the constructor is defined as inline, which is more efficient. Member functions contained in a file will not be defined repeatedly;
const at the end of the member function; Function: tells the system that this member function will not modify any member variables of the object;
member functions with const are also called constant member functions; add in the declaration const, also add const in the definition;
const Time abc; //Define const object;

1) //Constant objects and constant member functions
class A
{ public: void func(void)const { cout << “123” << endl; } void func1(void) { cout << “456” << endl; } };









int main(void)
{
const A a1;
a1.func(); //Only member functions with const can be called because they are constant objects;
A a2;
a2.func1(); //Member functions with const can be called , you can also call member functions without const;
return 0;
}

2) multitable, the opposite of const, in order to break through the limitations of const;
class A
{ public: void func(void)const //How to make a_ assignment effective? How to remove const attributes: mutable { a_ = 5; cout << “123” << endl; } A(int a) :a_(a) { cout << a_ << endl; } private: mutable int a_; //Modify member variables with mutable so that they can be used in const Modify the content of its variables in the member function; };












int main(void)
{
A a(4);
a.func();
return 0;
}

// this is the object itself! ! !
this has a (const) constant attribute; //The pseudo code is: Time
const this;
//In this pointer, adding const means that it can only point to the current object and cannot point to other objects;
class A
{ public: A& func1 (void) { cout << “123” << endl; return *this; } A& func2(void) { cout << “123----” << endl; return *this; } };











int main(void)
{
A a1;
a1.func1().func2(); //Implement the continuous calling mechanism
return 0;
}

//How to use static variables
class A
{ public: static int m_; //Declare static member variables static void show(void) { cout << “444” << endl; } };






int A::m_ = 20; //Do not add static when defining, add static when declaring

int main(void)
{
cout << A::m_ << endl; //The following three sentences print point to the same memory;
A a1;
cout << a1.m_ << endl;
A a2;
a2.m_ = 90;
cout << a2.m_ << endl;
return 0;
}

In debug mode: shift+F9 to quickly open monitoring mode

//Class-related non-member functions
class A
{ public: int a_; int b_; };



void printMsg(const A& obj)
{
cout << obj.a_ << " " << obj.b_ << endl;
}
int main(void)
{
A a1;
a1.a_ = 90;
a1.b_ = 40;
printMsg(a1);
return 0;
}

//In-class initialization
class A
{ public: int a_ = 6; //In-class initialization int b_ = 54; };



void printMsg(const A& obj) //Non-member function calling class
{ cout << obj.a_ << " " << obj.b_ << endl; } int main(void) { A a1; printMsg(a1); return 0; }







5) Initialization of const member variables: must be initialized with the constructor initialization list;
cannot be initialized by assignment;
class A
{ public: const int m; A(int a) :m(a) //const member variables must be Initialization list { cout << "constructor— m: " <<m<< endl; } };






int main(void)
{
A a(56);
return 0;
}

//A constructor without parameters is called the default constructor! ! !

6) The use of =default, =delete; =default introduced in C++11
: allows the system to generate a default constructor;
=delete; prohibits the system from generating a default constructor;

Learning on August 14:
Top-level const and bottom-level const are relative to pointers. The order of const modification is from left to right;
the top finger (thimble) is immutable and variable (int* const p;), and the bottom type (teardrop) is immutable and variable (const int* p); there is an idiom called (The thimble sheds tears)

Virtual function call
People* p2 = new Man(); //The parent class pointer new a subclass object
p2->eat();
p2->People::eat(); //Display the member function of the parent class being called

//p2 = new People();
//p2->eat();

//p2 = new Women();
//p2->eat();
//override can only be written in subclasses, and override can only be used in virtual functions;
final is also dedicated to virtual functions and is used in parent classes. It will be an error to try to overwrite the code of the parent class;
int main(void)
{
Man m1; //The following results are output normally
//people have argument constructor----
//man constructor----
//people have argument constructor ----
//man constructor----
Man* m2 = new Man(); You need to delete m2 manually; otherwise it will cause memory leaks. If you delete it manually, there is no problem.

People* p1 = new Man(); /父类指针指向子类对象
delete p1; //因为父类虚构函数没有设置为虚析构函数,没有执行子类的析构函数,造成内存泄漏;
//输出结果如下,	
//people default constructor---- 
//man constructor----
//~people  deconstructor----

return 0;

}

2) Friend functions and friend classes
class Man: public People
{ public: friend void func(const Man& obj); //Set func as the friend function of this class, and you can ask the private member function of this class; Man( ); ~Man() { cout << “~Man deconstructor----” << endl; } private: virtual void eat(void)const override { cout << “Man eats rice” << endl; } }; //As long as the function func becomes a friend function of class Man, then the func function can access all members of class Man; (including member variables and member functions) void func(const Man& obj) //If it is not set to func, the function is Friend function of Man class, the following code will compile errors; { obj.eat(); }

















Destined relationships cannot be inherited and are one-way and non-transitive;
learning of friend member functions;

3) The simplest way to write a friend class, the code is as follows:
class A
{ friend class B; // Declare B as your own friend class, so that you can ask your own private member mm; private: int mm = 6; };



class B
{
public:
void printMsg(const A& obj)
{
cout << obj.mm << endl;
}
};
int main(void)
{
A a;
B b;
b.printMsg(a);
return 0;
}

4) Friend member function case:
class B;
class A
{ public: void printMsg(const B& obj); };


class B
{ friend void A::printMsg(const B& obj); //You need to pay attention to the writing format of friend member functions private: int mm = 6; };



void A::printMsg(const B& obj)
{ cout << obj.mm << endl; } int main(void) { A a; B b; a.printMsg(b); return 0; } Key points: Class A and The order of Category B cannot be changed. Because: only when the definition of a class is seen, its member functions can be declared as friends of another class. Because this kind of declaration and definition dependency is inside; pay attention to the declaration writing format of friend member functions; the benefits of friends: allow certain non-member functions to access protected and private members of the class under certain circumstances; (public itself can be accessed)












5) typeid operator, returns the actual type of the pointer or referenced object;

int a = 20;
const int* const p = &a; //The correct way to write the format, 'p' is just a name, the preceding ' ' is the pointer type it represents;
Base
pb2 = dynamic_cast <Base*> ( new Derived); //Correct writing method must be remembered

Key point: In order for the two operators of RTTI (typeid and dynamic_cast) to work properly, the base class must have a virtual function, otherwise the results of the two operators may be wrong; because only with the existence of virtual functions, the two operators
can Can play the role of a dynamic type;
those who do often succeed, those who practice often arrive;
class Base
{ public: Base(void) { cout << “Base constructor” << endl; } virtual void func2(void) { cout << "func2 handle—" << endl; } };



class Derived : public Base
{
public:
Derived(void) { cout << “Derived constructor” << endl; }
void func(void) { cout << “func handle—” << endl; }
};

class Test : public Base
{

};
int main(void) //The parent class pointer points to the subclass object, but there is no way to call the member function of the subclass object; {
Base * bptr = new Derived(); Test* dptr = dynamic_cast<Test*>(bptr) ; //dynamic_cast is only used for conversion of pointers and references; //The pointer or reference of the base class object is converted to other pointers or references of [the same inheritance level]; if (dptr != nullptr) //If the conversion is successful, then It is not empty; if the test is converted to Test, it will not be successful, but if it is converted to Derived, it will be successful; { cout << "Conversion successful" << endl; //dptr->func(); } else { cout << "No conversion successful ” << endl; } return 0; } //dynamic_cast is mainly used for [safe downward transformation], [upward transformation] itself is safe, there is no need to use dynamic_cast; // When using static types, upward transformation is also safe, but downward transformation Type conversion not allowed! Implicit type conversion from a derived class to a base class is possible; the reverse is not possible. //The reference conversion fails, the system will throw an exception std::bad_cast; try() catch{} The test code is as follows: class Base { public:





















Base() {};
virtual void Show() { cout << “This is Base calss”; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << “This is Derived class”; }
};

int main()
{ //In the first case, the conversion is successfulDerived b; Base& base1 = b; Derived& der1 = dynamic_cast<Derived&>(base1); cout << "The first case:"; der1.Show(); cout << endl;






//第二种情况
Base a;
Base& base = a;
cout << "第二种情况:";
try {
    Derived& der = dynamic_cast<Derived&>(base);
}
catch (bad_cast)
{
    cout << "转化失败,抛出bad_cast异常" << endl;
}

}

6) typeid (pointer or reference) //typeid is an operator and returns a reference to a constant object; the
role of typeid: typeid is mainly used to compare whether two pointers point to the same type of object;
in the virtual function table, The first item is the type_info object;

7) final is used after the class, as shown below:
class Base final {}; //Indicates that this class can no longer be inherited;
static type: the type when the variable is declared, the static type is known;
dynamic type: refers to It is the type of the object in memory represented by the pointer or reference;
only base class pointers or references have inconsistencies between static and dynamic types;

The copy and assignment of parent class and subclass, the code is as follows:
class Base
{ public: Base() {}; virtual void Show() { cout << “This is Base calss”; } Base(const Base& obj) { cout < < “base copy constructor” << endl; } }; class Derived : public Base { public: Derived() {}; void Show() { cout << “This is Derived class”; } };













int main()
{ Derived d1; Base b1(d1); //The subclass object initializes the parent class object, but actually refers to the members of the parent class //The base class can only process its own members and cannot process members of the derived class; //Or as follows, call the copy assignment operator: Derived d1; Base b1; b1 = d1; return 0; }








Guess you like

Origin blog.csdn.net/qq_30143193/article/details/132345320