Classes and Objects
- Differences between 0.C/C++.
- 1. Classes and Objects
- Three Features of 2.C++.
- 2.1 Packaging (should be visible to you, should not be invisible to you)
- 2.2. Membership variables and membership methods -- relationships with objects?
- 3.this
- 4. Default functions in classes
- Initialization and destruction of classes in 4.1.C
- Constructors and Destructors in 4.2C++.
- 4.2.1 Constructor
- 4.2.2 Destructor
- 4.2.2 Differences between constructors and destructors
- Exercise 4.2.3: C++ Encapsulated Chain List (Friendly Relationships)
- 4.3 Copy Constructor
- 4.3.1 Copy Constructor
- 4.3.2 Shallow Copy Constructor
- 4.3.3 Why the parameter of a copy constructor must be a reference&
- 4.4. Overloaded functions of assignment operators (shallow copies, to implement their own deep copies)
- 4.5. Overloaded functions to take address operators
- 4.6. const-modified overloaded functions for address fetching operators
- 5. Temporary Objects
- 5.1 Optimization of Temporary Objects
- 5.2 Classification of Temporary Objects
- 5.3 Properties of Temporary Quantity
- 5.4 References improve the lifetime of temporary objects
- 6. Life cycle of the object
- 7. Class type return values: are brought out through temporary objects
- 8.Use of const and static to modify class members
- 8.1 const modifier
- 8.2 Interview Question: Briefly describe const
- 8.3 static modifier member
- 8.4 Function pointer calls function method at call point
- 8.5 Exercises
- 9. Single Case Mode
- 9.1 Design a headmaster class (single case mode: lazy mode)
- 9.1.1 Singleton Pattern Generates Class What is the Function Value Return Class
- 9.2 Abstract Principal Class into Model (Thread Security)
- 9.1 Unlocked
- 9.2 Locking
- 9.3 Double Lock
- 9.4 Hungry Man Mode: Greedy Loading
- 9.5 Lazy Mode: Delayed Loading
Differences between 0.C/C++.
C language: a process-oriented language
C Language: Computer Language
The drawback of C is that it separates attributes from behavior in design
- What is the purpose and meaning of computer language design?
Solve real-world problems with computers (simulate reality) - What simulates reality?
Structures - Entity Properties, Functions - Behaviors - What's in reality is called an entity--described by attributes and behaviors
C++: Object-Oriented Language
Classes and Objects:
- oop thought
0.1.C Language Structures
C Language Structures
typedef struct Data { int ma; int mb; }DATA; void SetValue(DATA* pdt,int a,int b) //assignment { pdt->ma=a; pdt->mb=b; } int main() { DATA val; setValue(&val,10,20); return 0; }
0.2 Linking variables to functions
Connect variables with functions-->Function pointers
typedef struct Data { int ma; int mb; void(*func)(struct Data*, int, int); }DATA; //void (*) (struct Data*,int,int); void SetValue(DATA* pdt, int a, int b) { pdt->ma = a; pdt->mb = b; } int main() { DATA val; val.func = &SetValue; val.func(&val, 10, 20); //Entity execution behavior can be understood //val.func(10,20); return 0; }
1. Classes and Objects
1.1 oop Thought (Thought of Object-Oriented Language)
1.2 Write a human
//class Class Identification class People { public: void eat(char* what) { std::cout << mname << " is eatting " << what << std::endl; } void sleep(char* _where) { std::cout << mname << " is sleepping at" << _where << std::endl; } void play() { std::cout << mname << " is playing doudou!" << std::endl; } private: char mname[10];//Full name bool msex;//Gender int mage;//Age }; /* Set point until end of class or next access qualifier */ /* Class default access qualifier private: */ int main() { //int a; //type generates variable People p1;//People Type Class Type Type Instantiation Object //Access qualifier, access failure //strcpy_s(p1.mname, strlen("xiaoming"), "xiaoming"); p1.eat("meat"); return 0; }
Three Features of 2.C++.
Three main features of C++:
Encapsulate Inheritance Polymorphism
Access Qualifier
From the set point until the end of the class or the next access qualifier, the default is private
1.public: arbitrary access
2.protected: in subclasses and classes of this class
3.private: in this class
2.1 Packaging (should be visible to you, should not be invisible to you)
Encapsulation is the protection of attributes and behaviors
The process should be: Ask for money, OK, and then Xiao Ming takes the money from his pocket and passes it to me
Attributes are private and need to be protected
Behavior is public,
Designing a student class
#include<iostream> class Student { private: char name[10]; bool sex; int age; public: void learn(const char* what)// { std::cout << name << "learning" << what << std::endl; } void eat(const char* when, const char* what) { std::cout << name << "eating" << what << "on" << when << std::endl; } void sleep(const char* when, const char* what) { std::cout << name << "sleeping at" << what << "on" << when << std::endl; } };
2.2. Membership variables and membership methods -- relationships with objects?
3.this
The statement that this pointer points to an object is too biased. This pointer points to the space occupied by the object (no resources)
The this pointer does not allow modifications and does not change (its stored address cannot change)
3.1 thiscall calling convention
Member Method Call Dependent Object Call
4. Default functions in classes
If not provided by the designer, six default functions are provided
1. Constructors
2. Destructors
3. Copy Constructor
4. Overloaded functions of assignment operators
5. Overloaded functions to take address operators
6. const-modified overloaded functions for address fetching operators
Initialization and destruction of classes in 4.1.C
Class initialization function:
Destroy function for class:
Main function call
Constructors and Destructors in 4.2C++.
4.2.1 Constructor
The function of the constructor:
Initialize the memory space occupied by the object (give the object the memory space resources)
Constructor (can be overloaded, make a difference)
There is a this pointer (if not, there is no way to determine which member variable to initialize)
It cannot be called artificially, it can only be called by the system (the constructor is thiscall call, depends on object call, the constructor is not completed, the object is not generated)
Constructor not completed: Object incomplete --->Semi-finished object
Steps to generate objects
- Open up the memory space occupied by the object <-----System provided
- Invoke Constructor (Memory Space Initialized Object)<----System Provided
What is the object?
Space + Resources
What is a variable?
space
What is the difference between definition and instantiation?
Definition--->Space (Exploration)
Instantiation --> Space + Resources (Exploit + Give Resources)
What should the system-provided constructors look like?
90 lines are ambiguous, 91 lines are the call to the default constructor
4.2.2 Destructor
Destructor (can't overload,'death is the same')
Role of destructors:
Release other resources occupied by objects
Destructor (can't overload,'death is the same')
Has this pointer
Can be called artificially
Realization:
Delete[] mname------>Destroy open content on the heap
Call time:
Destruction of objects:
1. Call destructors (release other resources occupied by objects)
2. The system releases the space occupied by the object--->the contents on the stack
4.2.2 Differences between constructors and destructors
1. The function of the constructor:
Initialize the memory space occupied by the object (give the object the memory space resources)
Constructor (can be overloaded, make a difference)
There is a this pointer (if not, there is no way to determine which member variable to initialize)
It cannot be called artificially, it can only be called by the system (the constructor is thiscall call, depends on object call, the constructor is not completed, the object is not generated)
2. The role of destructors:
Release other resources occupied by objects
Destructor (can't overload,'death is the same')
Has this pointer
It can be called artificially, but it degenerates into a normal function call, which is called again when the program is finished.
3. Differences:
Attributes that are naturally assigned are not modifiable and cannot be invoked artificially.
The process of extinction can be manipulated artificially.
4. Order of constructors and destructors:
Construct before destruct
Opening up space is in the stack, 1 goes into the stack then 23 goes into the stack, stack is first in then out, so when destroyed, 3 goes out of the stack first.
Exercise 4.2.3: C++ Encapsulated Chain List (Friendly Relationships)
Friendship:
1. Unidirectionality
#include<iostream> class CLink; //forward declaration class Node //Node Class { public: Node(int data = 0);//Give a default value private: //Data protection cannot be completed if private ownership is changed to public ownership int mdata; Node* next; friend class CLink; }; Node::Node(int data)//Scope preceded by function name--"means that a function is a member method of a class { mdata = data; next = NULL; } class CLink //Chain List Class--"Set of Nodes { public: CLink(); ~CLink(); //Head plug, end plug, delete print void InsertOfHead(int val); void InsertOfTail(int val); bool Empty(); bool DeleteOfHead();//To determine if it is empty bool DeleteOfTail(); void Print(); private: Node* phead; }; CLink::CLink() { phead = new Node(); //Head Pointer Points to Head Node } CLink::~CLink() { //Release Head Node and Data Node Node* p = phead; Node* tmp; while (p != NULL) { tmp = p->next; delete p; p = tmp; } phead = NULL; } void CLink::InsertOfHead(int val) { Node* s = new Node(val); s->next = phead->next; phead->next = s; } void CLink::InsertOfTail(int val) { Node* s = new Node(val); Node* tail = phead; while (tail->next != NULL) { tail = tail->next; } tail->next = s; } bool CLink::Empty() { //Is the pointer field of the header node empty return phead->next == NULL; } bool CLink::DeleteOfHead() { if (Empty()) { return false; } Node* q = phead->next; phead->next = q->next; delete q; } bool CLink::DeleteOfTail() { if (Empty()) { return false; } //Delete the last node, the last previous pointer should point to empty Node* tail0 = phead;//Second Last Node Node* tail = tail0->next;//Last Node while (tail->next != NULL) { tail0 = tail0->next; tail = tail0->next; } tail0->next = NULL; delete tail; return true; } void CLink::Print() { Node* p = phead->next; while (p!= NULL) { std::cout << p->mdata << " "; p = p->next; } std::cout << std::endl; } int main() { CLink cl; for (int i = 0; i < 5; ++i) { cl.InsertOfHead(i + 1); } cl.Print(); for (int i = 0; i < 5; ++i) { cl.InsertOfTail(i + 1); } cl.Print(); cl.DeleteOfHead(); cl.Print(); cl.DeleteOfTail(); cl.Print(); return 0; }
4.3 Copy Constructor
Generate new objects of the same type with an existing object
Must use reference when parameter to prevent recursive call to copy constructor
class CGoods { public: CGoods() { } CGoods(int amount) { mamount = amount; } CGoods(char* name, float price, int amount) { mname = new char[strlen(name) + 1](); strcpy_s(mname, strlen(name) + 1, name); mprice = price; mamount = amount; } //deep copy CGoods(const CGoods& rhs) { mname = new char[strlen(rhs.mname) + 1](); strcpy_s(mname, strlen(rhs.mname) + 1, rhs.mname); mprice = rhs.mprice; mamount = rhs.mamount; } /* 1. Prevent formal parameters from modifying the value of an argument 2. Receive Implicitly Generated Temporary Quantity----"Must Receive Temporary Quantity with Common Reference (Constant) */ //void CGoods& void operator=(const CGoods& rhs)//this: Left Operand Parameter: Right Operand { if (this == &rhs)//self assigning { return; } delete[] mname; mname = new char[strlen(rhs.mname) + 1](); strcpy_s(mname, strlen(rhs.mname) + 1, rhs.mname); mprice = rhs.mprice; mamount = rhs.mamount; } ~CGoods() { delete[] mname; mname = NULL; } private: char* mname; float mprice; int mamount; }; int main() { CGoods good1("Bread", 4.5, 100); CGoods good2 = good1;----->copy constructor CGoods good2("milk", 2.5, 1000); good2 = good1;//The compiler assigns values through overloaded functions of the -"assignment operator --->operator, as detailed in 4.4 return 0; }
4.3.1 Copy Constructor
copy constructor
4.3.2 Shallow Copy Constructor
Default copy constructor: shallow copy (consider implementing deep copy if member variables have pointers)
Pointing to the same memory area, when good2 is destroyed, mname memory is freed, and when good1 is destroyed, a duplicate release error occurs.
4.3.3 Why the parameter of a copy constructor must be a reference&
Copy Constructor If the parameter is not referenced, recursive calls generate the parameter object, resulting in stack overflow and program crash
4.4. Overloaded functions of assignment operators (shallow copies, to implement their own deep copies)
Assign an existing object to an existing object of the same type
Steps to construct:
1. Determine whether it is an assignment
2. Release old resources
3. Opening up new resources
4. Assignment
4.4.1 Questions frequently asked in interviews
4.4.1.1. Differences between class and struct
The default access qualifiers are different:
class: private struct: public
4.4.1.2. What is the size of an empty structure and why?What about empty classes?
C: (Memory blocks are carved out with a module, an empty structure is equivalent to a non-existent module, and memory blocks cannot be carved)
An empty structure cannot be defined
C++:
1 byte
Structures are handled as class types
Empty class:
1
Classes simulate Abstract concepts, which are abstracted from entities. Entities exist in reality. Therefore, C++ designers set the size of empty classes to 1 by default, and spatial objects can simulate entities.
struct Data { public: void Show() { std::cout << "hello world" << std::endl; } }; //Only member methods without member variables are considered empty classes class Test { public: void Show()//_thiscall { std::cout << "hello world!" << std::endl; } }; int main() { Test test;//Object that does not exist for test if 0 test.Show(); //Data val; //val.Show(); //std::cout << sizeof(struct Data) << std::endl; return 0; }
4.4.1.3. Return value type of assignment operator
class CGoods { public: CGoods() { mname = new char[1](); } CGoods(char* name, float price, int amount) :mname(new char[strlen(name) + 1]()), mprice(price), mamount(amount) { strcpy_s(mname, strlen(name) + 1, name); } CGoods(const CGoods& rhs) { mname = new char[strlen(rhs.mname) + 1](); strcpy_s(mname, strlen(rhs.mname) + 1, rhs.mname); mprice = rhs.mprice; mamount = rhs.mamount; } CGoods& operator=(const CGoods& rhs) { if (this != &rhs) { delete[] mname; mname = new char[strlen(rhs.mname) + 1](); strcpy_s(mname, strlen(rhs.mname) + 1, rhs.mname); mprice = rhs.mprice; mamount = rhs.mamount; } return *this; } ~CGoods() { delete[] mname; mname = NULL; } private: char* mname; float mprice; int mamount; }; int main() { int a = 10; int b = 20; int c; c = a = b;//continuous assignment CGoods good1("Bread", 4.5, 100); CGoods good2("Milk bread", 4.5, 100); CGoods good3; good3 = good2 = good1; //Good2 = good1; //good2 itself return 0; }
4.5. Overloaded functions to take address operators
4.6. const-modified overloaded functions for address fetching operators
5. Temporary Objects
Temporary object:
Lifetime: End of expression, encounter semicolon, end of life cycle
5.1 Optimization of Temporary Objects
Optimization of temporary objects:
5.2 Classification of Temporary Objects
- Explicitly generate temporary objects:
Specify exactly what temporary objects are generated - Implicitly generate temporary objects:
What temporary objects should compiler presentations generate
80 rows are implicitly generated and 82 rows are explicitly generated (type only, no object name, explicit generation)
5.3 Properties of Temporary Quantity
- Built-in Type---"Constant
- Custom Type----"Variable
- Implicitly Generated Temporary Object----"Constant
5.4 References improve the lifetime of temporary objects
References increase the lifetime of temporary objects the same as reference variables
95 lines of code: assigns the address of the temporary object to the pointer, which points to an invalid object when the temporary object is destroyed after the statement ends
6. Life cycle of the object
CGoods ggood1("g1", 4, 10);//.data static CGoods ggood2("g2", 2, 10);//.data---"Destroy after the entire program ends int main() { CGoods lgood1;//stack CGoods lgood2("l2", 10, 20);//stack static CGoods lgood3("l3", 30, 10);//.data---"Destroy after the entire program ends CGoods lgood4 = CGoods("l4", 40, 10);//stack CGoods lgood5 = 20;//stack (optimized generation, only lgood5 objects generated) lgood1 = CGoods("tmp", 20, 30);---->Not to generate new objects, all not optimized, expression completes temporary destruction, constructs, assignments, destructive calls lgood2 = 30; lgood3 = (CGoods)(10,20,30,40);//Strong comma expression {} /* comma expression The data ends up with the last one */ CGoods* pc1 = new CGoods("pc1", 10, 20);//heap CGoods* pc2 = new CGoods[2];//Heap has two object builds CGoods* pc3 = &CGoods("pc3", 10, 20); CGoods& rc3 = CGoods("rc3", 10, 20); delete pc1; delete[] pc2; return 0; } CGoods ggood3("g3", 3, 10);//.data
7. Class type return values: are brought out through temporary objects
Return value in:
1.<=4 eax
2. >4 && <=8 eax edx
3. >8 Temporary Volume
How many temporary quantities are generated?
A: five return value objects when test1, test2, arg, tmp, return.
class Test { public: Test(int a = 0) { ma = a; } Test(const Test& rhs) { ma = rhs.ma; } ~Test() { std::cout << "Test::~Test()" << std::endl; } private: int ma; }; Test getObject(Test arg) { Test tmp = arg; //... return tmp; } int main() { Test test1(20); Test test2; test2 = getObject(test1); return 0; }
class Test { public: Test(int a = 0) { std::cout << "Test::Test(int)" << std::endl; ma = a; } Test(const Test& rhs) { std::cout << "Test::Test(const Test&)" << std::endl; ma = rhs.ma; } void operator=(const Test& rhs) { std::cout << "Test::operator=(const Test&)" << std::endl; if (this == &rhs) { return; } ma = rhs.ma; } ~Test() { std::cout << "Test::~Test()" << std::endl; } private: int ma; }; /* Custom type as parameter References are typically set to references (references do not generate objects, one less construct and one less destruct) Efficiency Improvement */ Test getObject(Test& rhs)--->Reference does not generate { Test tmp = rhs;//2 //... return tmp;//An object was returned } int main() { Test test1(10);//1 Test rt = getObject(test1);//3---"return value passed in, resulting in optimization, generating rt only return 0; }
Initialization list of 7.1 constructors
8.Use of const and static to modify class members
8.1 const modifier
- Modify member variables: must initialize
- Modifying member methods: common methods
A normal object cannot call a normal method, but a normal object can only call a normal method (a common method risks modifying the value of a constant variable)
Common objects can call common methods
Normal member methods cannot be called in normal methods
Common methods can be called in normal member methods
class Test { public: Test(int a) : ma(a) {} void Show()const //const Test* const this; { std::cout << "ma:" << ma << std::endl; } void Print() { Show(); std::cout << "hello world!" << std::endl; } private: int ma; }; int main() { Test test(10);//Constant Object test.Show(); return 0; }
8.2 Interview Question: Briefly describe const
1. Variables: C/C++.
2. Modification request processing is not allowed
3.const modifies member variables
8.3 static modifier member
1. Modify member variables:
Initialization: member variables are not objects, belong to classes (which are shared by all objects), and must be initialized outside the class
Access: Not dependent on Object Access
2. Modifying member methods:
_cdecl cannot access normal member variables without this pointer
Access only: global variable static member variable
Access: Not dependent on Object Access
Static member methods cannot call normal member methods
Normal member methods can call static member methods
Memory space occupied by constructor initialization object
Static member variables do not belong to objects, so constructors cannot initialize static member variables
class Test { public: Test(int b) : mb(b) {} static void Show()//cdecl does not have this pointer { //Print(); std::cout << "ma:" << ma << std::endl; //std::cout << "mb:" << mb << std::endl; } void Print()//thiscall { std::cout << "mb:" << mb << std::endl; Show(); } static int ma; private: int mb; }; int Test::ma = 10; int main() { Test test1(10); Test test2(20); std::cout << test1.ma << std::endl; std::cout << Test::ma << std::endl;// test1.Show(); Test::Show(); test1.Print(); return 0; }
8.4 Function pointer calls function method at call point
//int (*) (int,int) int Sum(int a, int b) { std::cout << "::Sum(int,int)" << std::endl; return a + b; } class Test { public: Test(int a) :ma(a) {} void Show() { std::cout << "ma:" << ma << std::endl; } private: int ma; }; /* void (*) (); //Test:: */ /* .* ->* When a function pointer points to a class member method */ int main() { int(*Func) (int, int); Func = ∑ (*Func)(10, 20); //Sum(10, 20); Test test(10); ------>Dependent Object Call void(Test::* cppfunc)() = &Test::Show; (test.*cppfunc)(); Test* ptest = new Test(20); (ptest->*cppfunc)(); return 0; }
8.5 Exercises
class String { public: //NULL String(char* ptr) { assert(ptr!=NULL); if(ptr==NULL) { return; } mptr = new char[strlen(ptr) + 1](); strcpy_s(mptr, strlen(ptr) + 1, ptr); } String(const String& rhs) { mptr = new char[strlen(rhs.mptr) + 1](); strcpy_s(mptr, strlen(rhs.mptr) + 1, rhs.mptr); } String& operator=(const String& rhs) { if (this == &rhs) { return *this; //---->Left Operand } delete[] mptr; mptr = new char[strlen(rhs.mptr) + 1](); strcpy_s(mptr, strlen(rhs.mptr) + 1, rhs.mptr); return *this; } ~String() { delete[] mptr; mptr = NULL; } private: char* mptr;// }; int main() { String str("hello"); String str2 = str; str2 = str; return 0; }
9. Single Case Mode
Design Mode Singleton mode Class can only produce one object 1. Screen the interface of the generated object Place the constructor in private 2. Provide interfaces to generate unique objects 1. cannot be returned in the form of a class type 2.static
9.1 Design a headmaster class (single case mode: lazy mode)
/* An interface is designed to generate objects static is usually written out */ class Rector { public: static Rector* getInstance(char* name, int age, bool sex)//----"Get Instances { if (pre == NULL) { pre = new Rector(name, age, sex); } return pre; } private: Rector(char* name, int age, bool sex) { mname = new char[strlen(name) + 1](); strcpy_s(mname, strlen(name) + 1, name); mage = age; msex = sex; } char* mname; int mage; bool msex; static Rector* pre;//Identifies that the unique object does not belong to the scope of the entire class }; Rector* Rector::pre = NULL; int main() { Rector * pr1 = Rector::getInstance("zhangsan", 45, true); Rector * pr2 = Rector::getInstance("zhangsan", 45, true); Rector * pr3 = Rector::getInstance("zhangsan", 45, true); //Rector re1("zhangsan", 45, true); //Rector re2("lisi", 45, true); return 0; }
9.1.1 Singleton Pattern Generates Class What is the Function Value Return Class
&, * both because no temporary object is generated (generating a temporary object results in two objects, and the singleton pattern is unique)
Both constructors and copy constructors can generate objects, so not only should construction be considered, but also copy construction, so 9.1 code is not perfect
9.2 Abstract Principal Class into Model (Thread Security)
9.1 Unlocked
1. Unlocked Conditions: Unsafe Factors
9.2 Locking
2. After unlocking, the first time the security is guaranteed, but the second time the third time the unlock still needs to be unlocked, resulting in resource consumption
9.3 Double Lock
3. Face Resource Consumption: Double Lock Single Case Mechanism
9.4 Hungry Man Mode: Greedy Loading
Threads are an execution path for a process
Processing in threads generates unique objects--->Unsafe
Generate Unique Object Before Thread Opens---"Security
class SingleTon { public: static SingleTon* getInstance() //Generate an interface { return psing; } private: SingleTon() {} SingleTon(const SingleTon&); static SingleTon* psing;//.data }; SingleTon* SingleTon::psing = new SingleTon();//Before main executes int main() { SingleTon* psingle1 = SingleTon::getInstance(); SingleTon* psingle2 = SingleTon::getInstance(); SingleTon* psingle3 = SingleTon::getInstance(); return 0; }
9.5 Lazy Mode: Delayed Loading
class SingleTon { public: static SingleTon* getInstance() { if (psing == NULL)//Thread Security Second and Later { lock(); if (psing == NULL) { psing = new SingleTon(); } unlock(); } return psing; } private: SingleTon() { } SingleTon(const SingleTon&); static SingleTon* psing; }; SingleTon* SingleTon::psing = NULL; int main() { SingleTon* psingle1 = SingleTon::getInstance(); SingleTon* psingle2 = SingleTon::getInstance(); SingleTon* psingle3 = SingleTon::getInstance(); return 0; }