網(wǎng)站首頁 編程語言 正文
this及返回自身對象的引用
this:調(diào)用成員函數(shù)的時候,編譯器負(fù)責(zé)把對象地址傳(&myTime)遞給成員函數(shù)中隱藏的this形參。
在系統(tǒng)角度來看,任何對類成員的直接訪問都是被this隱式調(diào)用的。
- this有個const修飾符,只能用來指向已確定的那個對象,不能更改。
- this只能在成員函數(shù)中使用,全局函數(shù)靜態(tài)函數(shù)不能使用this。
- 在成員普通函數(shù)中,this是一個指向非const對象的const指針。(this 等價于 Time *const this,const修飾this,this不能指向其他對象,但this指向的對象中的成變量可以被修改。)
- 在const成員函數(shù)中,this指針是一個指向const對象的const指針(this 等價于 const Time * const this)。
class Time {
public:
?? ?int hour;
?? ?int minute;
public:
?? ?//把對象自己返回去了
?? ?Time& add_hour(int temp_hour);
?? ?Time& add_minute(int minute);
};
//實際工作中,this能省則省。
Time& Time::add_hour(int temphour) ?{
?? ?this->hour += temphour;//等價于 hour += temphour;
?? ?return *this;//把對象自己返回去了,固定寫法。指向本對象的指針。*this表示對象本身。
}
Time& Time::add_minute(int minute) {
?? ?this->minute += minute;//區(qū)分成員變量和形參
? ? return *this;
}
?? ?Time myTime;
?? ?myTime.add_hour(3);
?? ?myTime.add_hour(3).add_minute(10);//返回自己,可以連續(xù)調(diào)用。
c++如何返回對象
返回對象,無非兩種方式,返回棧對象和堆對象指針,棧對象指針不能返回,因為可能使用不該使用的內(nèi)存,堆對象也不能直接返回,因為會產(chǎn)生內(nèi)存泄漏。下面,我們分析兩種返回方式的優(yōu)缺點,及針對缺點的解決方案。
這里有個注意點,返回this指針指向的自身對象時,可以返回引用。
返回棧對象
- 優(yōu)點:不用手動釋放內(nèi)存,避免了內(nèi)存泄漏;
- 缺點:會產(chǎn)生對象拷貝,如果對象比較大,比如,對象里面有大數(shù)組,會產(chǎn)生性能開銷。
返回堆對象指針
- 優(yōu)點:不會產(chǎn)生對象拷貝,對性能友好;
- 缺點:函數(shù)調(diào)用之后手動釋放對象,代碼管理難度和內(nèi)存泄漏風(fēng)險提高。
那有沒有辦法,把上面的缺點全克服了呢?有!
- 返回棧對象:用移動構(gòu)造函數(shù)減少大對象拷貝;
- 返回堆指針:借助智能指針,避免內(nèi)存泄漏。
注意:返回棧對象時,雖然很多編譯器做了編譯優(yōu)化,即使不寫移動構(gòu)造函數(shù),也不會產(chǎn)生對象拷貝,但是,為了應(yīng)對還沒有編譯優(yōu)化的編譯器,建議寫好移動構(gòu)造函數(shù)。
可以看下面代碼。
#include <iostream>
using namespace std;
class A{
public:
int i;
string* bigObj; //假設(shè)這是大對象
A(){
bigObj=new string("abc");
cout<<"A created."<<endl;
}
~A(){
if(bigObj!=nullptr){
delete bigObj;
bigObj=nullptr;
}
cout<<"A delete."<<endl;
}
A(const A &a):i(a.i),bigObj(new string(*(a.bigObj))){
cout<<"A copied."<<endl;
}
//建議在類里面寫好移動構(gòu)造函數(shù),解決返回對象時對象拷貝帶來的性能開銷。
A(A&& a):i(a.i),bigObj(a.bigObj){
a.bigObj=nullptr;
cout<<"A moved."<<endl;
}
};
//如果沒有編譯器優(yōu)化,如果沒有移動構(gòu)造函數(shù),這種寫法調(diào)用拷貝構(gòu)造函數(shù),產(chǎn)生對象復(fù)制
A GetAInstance1(){
A a;
return a;
}
//這種寫法運行沒問題,但是要在函數(shù)調(diào)用之后手動釋放對象,
//代碼管理難度和內(nèi)存泄漏風(fēng)險提高。
A* GetAInstance2(){
A* a=new A;
return a;
}
//這種寫法沒問題
unique_ptr<A> GetAInstance3(){
unique_ptr<A> a(new A);
return a;
}
//這樣返回會造成內(nèi)存泄漏
A GetAInstance4(){
A* a=new A; //此處的a無法釋放
return *a;
}
//這樣返回會使用不該使用的內(nèi)存,造成程序運行不穩(wěn)定
A* GetAInstance5(){
A a;
return &a;
}
int main(int argc, const char * argv[]) {
A a1=GetAInstance1();
cout<<"-----------------"<<endl;
A* a2=GetAInstance2();
delete a2;
cout<<"-----------------"<<endl;
unique_ptr<A> a3=GetAInstance3();
cout<<"Main Over"<<endl;
return 0;
}
原文鏈接:https://blog.csdn.net/u014339447/article/details/109496593
相關(guān)推薦
- 2022-08-25 利用Python實現(xiàn)一個簡易的截圖工具_(dá)python
- 2022-04-04 運行npm run dev報錯(已解決)
- 2022-07-16 Date 轉(zhuǎn)為 LocalDate
- 2022-08-10 C#多線程之線程綁定ThreadLocal類_C#教程
- 2022-06-01 Android實現(xiàn)極簡打開攝像頭_Android
- 2023-04-17 Linux命令學(xué)習(xí)之用戶切換su,sudo命令詳解_linux shell
- 2022-05-08 記一個React.memo引起的bug_React
- 2022-08-11 python?tkinter中的錨點(anchor)問題及處理_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支