当前位置:网站首页>Deep operator overloading (2)
Deep operator overloading (2)
2022-07-01 15:29:00 【baobaobashi_】
Deep operator overloading (2)
Catalog
- Deep operator overloading (2)
- 1、 Operator overload , When to return by reference , When to return as a value ?
- 2、 The three functions of constructors
- 3、 What is type conversion
- 4、 Constructors use the difference between initializing lists and assigning values
- 5、 Construction order of class data members
- 6、 Object lifetime management
- 7、* Operators and -> The difference between returning objects after operator overloading
1、 Operator overload , When to return by reference , When to return as a value ?
Returns... As a value :
Int operator+(const Int& it)
{
this->value += it.value;
return Int(this->value + it.value);
}
Returns... By reference :
Int &operator+=(const Int &it)
{
this->value += it.value;
return *this;
}
a += b;
summary : When an operator returns itself , Returns... By reference . But when returning the dead value , You need to use a value to return .
2、 The three functions of constructors
class Int
{
private:
int value;
public:
//1 2 3
Int(int x = 0):value(x)
{
cout << "Int()" << this << endl;
}
Int(const Int &it):value(it.value)
{
cout << "Copy Int:" << this << endl;
}
Int &operator=(const Int &it)
{
if(this != &it)
{
value = it.value;
}
cout << this << " = " << &it << endl;
return *this;
}
}
int main()
{
Int a = 10; // Custom type
//Int a(10);
int b = 100; // Built in type
a = b;
}
The three functions of constructors :
- Building objects
- Initialize object
- Type conversion ( Only single parameter constructors )
3、 What is type conversion
Let's look at the following example
problem : Above main Function , Could you please b Assign a value to a?
answer : The third function of constructor , Type conversion
First of all, let's observe , One is int type , One is custom Int type . If you will b to a assignment , Obviously, it can't pass , But the compiler did not report an error , What's the matter ?
We will b To convert , Convert to custom type . Then give the converted type to a assignment .
By calling, we can find :
We create a temporary object with the address 012FF690, Then assign the temporary object to a object .
Let's take a look at the process of deconstruction :
~Int()
{
cout << "Destroy Int: " << this << endl;
}
It can be found that the temporary object will be destroyed after assignment .
3.1 The constructor that can be type converted here must be single parameter .
// Constructors
Int(int x,int y):value()
{
cout << "Int()" << this << endl;
}
int main()
{
Int a(10,20);
int b = 100;
a = b; //error: Must contain only one parameter
}
If the initial value of a parameter is changed, it can also be regarded as a parameter :
Int(int x,int y = 0):value()
{
cout << "Int()" << this << endl;
}
int main()
{
Int a(10);
int b = 100;
a = b; //right : Given a default value
}
problem :a What is the value of alpha ?
Int(int x,int y = 0):value(x + y)
{
cout << "Int()" << this << endl;
}
int main()
{
Int a(1,2);
int b = 100;
//a = b;
//a = b,20; // The comma operator , The rightmost one shall prevail .
//a = (Int)(b,20); // It is also a comma expression , take 20, That is to say (Int) 20;
//a = Int(b,20); // Call the constructor of two parameters , Create an anonymous object , take 20 to y,b to x, The result is 120;
}
Finally, both generate temporary objects , The first is to call the constructor according to the type conversion , The second kind produces an anonymous object , Receive two parameters .
Take up the above question , If you give two parameters , Don't initialize by default ?
Int(int x,int y):value(x + y)
{
cout << "Int()" << this << endl;
}
int main()
{
Int a(10,20);
int b = 100;
a = (Int)(b,100); //error: Force the form to create an unknown object
a = Int(b,100); //right: Call the constructor to create an anonymous object
}
For objects whose type is strongly converted to type , We can only give one valid parameter , More error
3.2 If implicit constructors are not allowed : Add before constructor explicit keyword .
...
explicit Int(int x = 0):value(x)
{
cout << "Int()" << this << endl;
}
...
int main()
{
Int a(10);
int b = 100;
a = b; //error, Cannot implicitly type cast
a = (Int) (200); //right, After forced conversion, you can
}
3.3 Can we assign variables to objects ?
explicit Int(int x):value(x)
{
cout << "Create Int:" << this << endl;
}
int main()
{
Int a(10);
int b = 100;
a = (Int)b;
b = a; //error
b = (int)a; // Try type conversion :error
}
You can't do this , We have no default function of cast type . We need to write it ourselves . The return type is a strong conversion type ( The system gives )
operator int()const
{
return value;
// The return type is a strong conversion type
}
int operator int()const
{
return value;
}
// If this is the case, it is just :
// b = (int)a;
// If that's the case :b = (float)a;
// It is impossible to write another float Overloaded function of type
// Of the above code main function
int main()
{
Int a(10);
int b = 100;
a = (Int)b;
b = a;
// Call the strong conversion function
// amount to :b = a.operator int();
// amount to :b = operator int(&a);
b = (int)a;
}
summary :
- When you need to assign a built-in type to an object , We can force conversion , Construct anonymous objects through single parameter constructors ;
- When you need to assign an object to a built-in type , You can overload functions by operators .
3.4 mutable Keywords and functors
There are the following categories :
class Add
{
mutable int value;
// Even if
public:
Add(int x = 0) : value(x) {
}
int operator()(int a,int b) const
// add to const value Will not be modified , You can give value add to mutable keyword
{
value = a + b;
return value;
}
};
as follows main function :
int main()
{
int a = 10,int b = 20, c = 0;
Add add;
c = add(a,b); // functor
}
Concept of imitative function : Imitative function is imitative function , It means that its function is similar to that of a function, but it is not a real function , Imitative function is also called function object . stay C++ It calls the operator by overloading the function, that is () Operator .
problem : The sentence of assignment add How objects call constructors ?
add Constructor will not be called , Will call the functor
c = add(a,b); // We overloaded the bracket operator
// amount to :
c = add.operator()(a,b);
More complicated situation :
int main()
{
int a = 10, b = 20, c = 0;
c = Add()(a,b);
}
Type name plus () Call constructor , Generate a dead value object , And then call your own
() Operator overloading , take a and b Add up , Finally assign to c.
summary :
- By mutable Modified member variables , Even if it is this Pointer add const Modification can also be modified .
- Any operator overloaded with parentheses , We call it affine function . When you meet someone ( ) Pay attention to , It may be object construction , It may be to call a functor .
4、 Constructors use the difference between initializing lists and assigning values
Think about the output of the following code :
#include<iostream>
using namespace std;
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Int()" << this << endl;
}
Int(const Int &it):value(it.value)
{
cout << "Copy Int:" << this << endl;
}
Int &operator=(const Int &it)
{
if(this != &it)
{
value = it.value;
}
cout << this << " = " << &it << endl;
return *this;
}
~Int()
{
cout << "Destory Int:" << this << endl;
}
};
class Object
{
int num;
Int val; //Int Type object
public:
Object(int x,int y)
{
num = x;
val = y;
cout << "create Objcet:" << this << endl;
}
~Object()
{
cout << "destroy Object:"<< this << endl;
}
};
int main()
{
Object obj(1,2);
}
process analysis :
Output results :
Initializing the list has the same effect as assigning values in the constructor ( Built in types only )
Object(int x,int y):num(x) // Equivalent assignment statement
{
cout << "Create Object:"<< this << endl;
//num = x; // Equivalent to initializing the list
val = y;
}
But custom types are different , There is no need to construct temporary objects
Object(int x,int y):num(x),val(y)
{
cout << "Create Object:"<< this << endl;
//num = x; // Equivalent to initializing the list
//val = y;
}
summary : For built-in types , Same efficiency ; For initialization of custom types , Try to initialize the list , Save a space .
5、 Construction order of class data members
Build in design order
#include<iostream>
using namespace std;
class Object
{
int num;
int sum; // Related to defining data
public:
Object(int x = 0):sum(x),num(sum)
{
}
void Print()const
{
cout << num << " " << sum << endl;
}
};
C++ The construction of class data members in is independent of the order of initializing members in the list , It is related to the data defined in the class data member and the class .
process analysis :
- The first is num, The second is sum. According to the compiler, all data members will be initialized to 0, To assign a value .
- num Constructed first , take sum The value is assigned to num. But at this time sum Not constructed , yes 0 Or random numbers , Assign this value to num.
- Later x The value is assigned to sum.
6、 Object lifetime management
class Object
{
Int *ip;
public:
Object(Int *s = NULL):ip(s) {
}
~Object()
{
if(ip != NULL)
{
delete ip;
}
ip = NULL;
}
};
int main()
{
Object obj(new Int(10));
//new Three functions of
//1、 Apply for space from the pile area
//2、 Call constructor , Construction object
//3、 Return the address of the object
}
process analysis :
- new There are three functions , First, a space will be opened up from the pile area , Then call the constructor to build the object , Finally, the address of the object will be returned . take 10 Store in the open space , The pointer s To point to this space , In the constructor, you will also put s To assign to ip.
- After the object ends , If ip It's empty , Delete ip. take ip Assign to null .
What are the benefits of doing so ?
Can be Int The lifetime of objects is automatically managed , We will compare the upper and lower codes .
Manual management :
int fun()
{
Int *ip = new Int(10);
...
delete ip; // If there is no such step , There will be a memory leak , By us manually
}
int main()
{
fun();
}
Automatic management :
int fun()
{
Object obj(new Int(10));
// Space requested in the stacking area , If fun End of the function ,obj Local objects will be destroyed , Will call its destructor . And its destructor has delete, Automatically by the system
}
int main()
{
fun();
}
7、* Operators and -> The difference between returning objects after operator overloading
Analyze the following code :
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Int()" << this << endl;
}
Int(const Int &it):value(it.value)
{
cout << "Copy Int:" << this << endl;
}
Int &operator=(const Int &it)
{
if(this != &it)
{
value = it.value;
}
cout << this << " = " << &it << endl;
return *this;
}
~Int()
{
cout << "Destory Int:" << this << endl;
}
int &Value()
{
return value;
}
const int &Value()const
{
return value;
}
};
class Object
{
Int *ip;
public:
Object(Int *s = NULL):ip(s) {
}
~Object()
{
if(ip != NULL)
{
delete ip;
}
ip = NULL;
}
Int &operator*()
{
return *ip;
}
const Int& operator*() const
{
return *ip;
}
Int *operator->()
{
return ip;
}
const Int* operator->() const
{
return ip;
}
};
int main()
{
Object obj(new Int(10));
Int *ip = new Int(10);
(*ip).Value();
(*obj).Value();
obj->Value();
ip->Value();
}
heavy load * What is returned is the object itself , The overloaded pointer returns the point of the object .
Why? , Let's look at the concept of combination :
Combine :
- Value type
- Pointer types
- Reference type ( The most complicated )
The first combination is the most common ,val The object is the whole Object Part of class .
Combination of the second pointer type ,ip Not at all Object Part of class , It's a weak correlation , The object pointed to by the pointer can be changed .
If you use Yes ip Visit , Returns the object In itself . If you pass *-> Visit , What you get is the stack area Address **.
Third, the combination modifies the objects in the class by reference , It's a strong connection , modify val Objects can affect .
Knowing this, we can -> Make further modifications :
Int * opearotr->() // heavy load -> Operator
{
return &**this;
//return ip; // What is returned is the address of the object
}
const Int *opearotr->()const
{
return &**this;
//return ip;
}
problem :&**this How to understand it ?
this The pointer points to the current object ,*this It means the object itself .
One more Namely * * this, He will call overloaded function , The alias of the object pointed to is returned ( return * ip).
Then add &, And dereference cancel each other , Namely ip The address of .
that , Return to the original code , Why de quote plus . Energy and harmony -> It has the same effect ?
class Int
{
private:
int value;
public:
Int(int x = 0):value(x)
{
cout << "Int()" << this << endl;
}
Int(const Int &it):value(it.value)
{
cout << "Copy Int:" << this << endl;
}
Int &operator=(const Int &it)
{
if(this != &it)
{
value = it.value;
}
cout << this << " = " << &it << endl;
return *this;
}
~Int()
{
cout << "Destory Int:" << this << endl;
}
int &Value()
{
return value;
}
const int &Value()const
{
return value;
}
};
class Object
{
Int *ip;
public:
Object(Int *s = NULL):ip(s) {
}
~Object()
{
if(ip != NULL)
{
delete ip;
}
ip = NULL;
}
Int &operator*()
{
return *ip;
}
const Int& operator*() const
{
return *ip;
}
Int *operator->()
{
return ip;
}
const Int* operator->() const
{
return ip;
}
};
int main()
{
Object obj(new Int(10));
Int *ip = new Int(10);
(*ip).Value();
(*obj).Value();
obj->Value();
ip->Value();
}
Before you create an object , Would be obj Objects and p Object allocation space .obj There is a pointer object in the object , So take 4 Bytes (32 position );p Objects are traditional pointer objects , Also accounted for 4 Bytes .
When you want to construct obj When the object , Will first construct its temporary object parameters , Create a space in the heap to store anonymous objects , The value is 10. next p Object also needs to create an anonymous object , from p Point directly at it , The value is 1.
next p What I visited was p The content of the resulting space ; and * obj You need to call Operator overload function , What is returned is after dereference ip, That is to say, it's worth 10 Temporary object temporary object , adopt Value To get its value .
p->Value() There's nothing to say . The key lies in obj->Value(), The first call -> Overload operator .*obj Meaning is to get ip,**obj Namely * ip, Get the contents of the temporary object .& *ip,& and * Offset each other , Namely ip.ip->Value(), And the most common p->Value() similar .
边栏推荐
- [advanced ROS] lesson 5 TF coordinate transformation in ROS
- 【STM32-USB-MSC问题求助】STM32F411CEU6 (WeAct)+w25q64+USB-MSC Flash用SPI2 读出容量只有520KB
- Is JPMorgan futures safe to open an account? What is the account opening method of JPMorgan futures company?
- Beilianzhuguan joined the dragon lizard community to jointly promote carbon neutralization
- 摩根大通期货开户安全吗?摩根大通期货公司开户方法是什么?
- Intelligent operation and maintenance practice: banking business process and single transaction tracking
- Introduction to MySQL audit plug-in
- opencv学习笔记五--文件扫描+OCR文字识别
- MySQL service is starting. MySQL service cannot be started. Solution
- Redis high availability principle
猜你喜欢
"Qt+pcl Chapter 6" point cloud registration ICP Series 6
IDEA全局搜索快捷键(ctrl+shift+F)失效修复
做空蔚来的灰熊,以“碰瓷”中概股为生?
Introduction to MySQL audit plug-in
Stm32f4-tft-spi timing logic analyzer commissioning record
Hardware design guide for s32k1xx microcontroller
雷神科技冲刺北交所,拟募集资金5.4亿元
【STM32学习】 基于STM32 USB存储设备的w25qxx自动判断容量检测
Qt+pcl Chapter 9 point cloud reconstruction Series 2
MySQL高级篇4
随机推荐
Implementation of wechat web page subscription message
[advanced ROS] lesson 5 TF coordinate transformation in ROS
Is JPMorgan futures safe to open an account? What is the account opening method of JPMorgan futures company?
Survey of intrusion detection systems:techniques, datasets and challenges
【STM32-USB-MSC问题求助】STM32F411CEU6 (WeAct)+w25q64+USB-MSC Flash用SPI2 读出容量只有520KB
What if you are always bullied because you are too honest in the workplace?
Shopping mall 6.27 to be completed
cmake 基本使用过程
Summary of point cloud reconstruction methods I (pcl-cgal)
What data capabilities do data product managers need to master?
leetcode:329. Longest increasing path in matrix
Introduction to MySQL audit plug-in
"Qt+pcl Chapter 6" point cloud registration ICP Series 6
Implementation of deploying redis sentry in k8s
TS reports an error don't use 'object' as a type The `object` type is currently hard to use
Opencv Learning Notes 6 -- image mosaic
Hardware design guide for s32k1xx microcontroller
STM32F4-TFT-SPI时序逻辑分析仪调试记录
【STM32学习】 基于STM32 USB存储设备的w25qxx自动判断容量检测
将ABAP On-Premises系统连接到中央检查系统以进行自定义代码迁移