当前位置:网站首页>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 .
边栏推荐
- 微信小程序02-轮播图实现与图片点击跳转
- 【目标跟踪】|模板更新 时间上下文信息(UpdateNet)《Learning the Model Update for Siamese Trackers》
- skywalking 6.4 分布式链路跟踪 使用笔记
- Task.Run(), Task.Factory.StartNew() 和 New Task() 的行为不一致分析
- Shopping mall 6.27 to be completed
- Flink 系例 之 TableAPI & SQL 与 Kafka 消息插入
- [target tracking] |stark
- 如何实现时钟信号分频?
- 关于用 ABAP 代码手动触发 SAP CRM organization Model 自动决定的研究
- Wechat applet 02 - Implementation of rotation map and picture click jump
猜你喜欢
Don't ask me again why MySQL hasn't left the index? For these reasons, I'll tell you all

Fix the failure of idea global search shortcut (ctrl+shift+f)

Filter & (login interception)
SQL常用的四个排序函数梳理

Guide de conception matérielle du microcontrôleur s32k1xx

Survey of intrusion detection systems:techniques, datasets and challenges

opencv学习笔记四--银行卡号识别

Introduction to MySQL audit plug-in

如何实现时钟信号分频?

雷神科技冲刺北交所,拟募集资金5.4亿元
随机推荐
将ABAP On-Premises系统连接到中央检查系统以进行自定义代码迁移
微信小程序01-底部导航栏设置
雷神科技冲刺北交所,拟募集资金5.4亿元
STM32ADC模拟/数字转换详解
《QT+PCL第六章》点云配准icp系列4
Opencv Learning Notes 6 -- image feature [harris+sift]+ feature matching
Tiantou village, Guankou Town, Xiamen special agricultural products Tiantou Village special agricultural products ant new village 7.1 answer
Tableapi & SQL and Kafka message insertion in Flink
Filter & (login interception)
使用 csv 导入的方式在 SAP S/4HANA 里创建 employee 数据
Shopping mall 6.27 to be completed
说明 | 华为云云商店「商品推荐榜」
微信公众号订阅消息 wx-open-subscribe 的实现及闭坑指南
Hidden rules of the workplace that must be understood before 30
What is the relationship between network speed, broadband, bandwidth and traffic?
Stm32f4-tft-spi timing logic analyzer commissioning record
These three online PS tools should be tried
《性能之巅第2版》阅读笔记(五)--file-system监测
openssl客户端编程:一个不起眼的函数导致的SSL会话失败问题
swiper 轮播图,最后一张图与第一张图无缝衔接