[英]When the return type is a class, what's the name of the pointer to the return value?
一個例子:
class A
{
....
A func();
};
A A::func()
{
...
return something;
}
在匯編級別,編譯時,函數A::func
實際上將具有兩個參數:第一個是this
指針,第二個是由調用方創建的用於存儲返回值的temp A
對象的地址。
例如,如果我們編寫a.func()
,程序將在堆棧中創建一個temp A
對象(我們將其稱為t
),並將a
的地址作為第一個參數傳遞, t
的地址作為第二個參數傳遞,最后調用函數func
。
這里是我的問題:在實現A::func
,我們可以得到的地址a
-它的指針this
; 但是我們有辦法得到t
的地址嗎? 它叫什么名字?
例如,如果我想在返回結果之前進行一些內存分配/釋放操作,則擁有它會很有用。
這是我想做的一個例子:
class A
{
int * data;
A func();
};
A A::func()
{
// here "ret_p" is the pointer to the return value (let's pretend that it exists)
ret_p->data = new int[some length];
...
return * ret_p;
}
當然,我可以在A::func
創建一個本地對象,然后將其返回。 但是程序會在我的本地對象和調用者創建的臨時對象之間進行復制。 由於調用者已經創建了一個臨時對象,所以我希望直接使用它可以節省時間和空間。 那可能嗎?
好吧,這可能不是c ++,但我仍然希望...
堆棧中沒有這樣的temp A
對象參數( t
)。
如果調用A a1 = a.func();
並return something;
在內部,將調用copy constructor
,等效於此A a1(something);
。 a1
和something
是不同的實例。
如果您A a1; a1 = a.func();
A a1; a1 = a.func();
並return something;
在里面, a1 = something; // (operator =)
a1 = something; // (operator =)
將被調用。 a1
和something
是不同的實例。
如果調用A a1 = a.func();
並return A(p1);
在內部,這等效於A a1(p1);
,有一個實例a1
。
如果調用a.func();
直接分配給var而不return something;
在內部,返回時什么也沒有發生。
如果調用a.func();
直接而不分配給var並return A(p1);
在內部,將構造一個臨時對象,然后立即銷毀它。
如果您A a1; a1 = a.func();
A a1; a1 = a.func();
並return A(p1);
在內部,將構造一個臨時對象,然后將operator =稱為a1 = temp object;
然后臨時對象將被銷毀。
供你參考。
畢竟, A a1 = a.func()
或A a1; a1 = a.func()
A a1; a1 = a.func()
, return something; // a var
return something; // a var
或return A(p1); // call constructor
return A(p1); // call constructor
會導致不同的行為,我認為您可以正確控制內存。
向func
提供&a
是復制省略的一種形式。
根本無法保證會發生這種情況,也沒有C ++級別的實現訪問。
當您說“我想在返回結果之前先分配一些內存/釋放內存”時,我認為您不清楚自己的想法,您能舉一個具體的例子嗎? 復制省略,移動運算符和RAII可能使您所需的一切成為可能。
響應您的示例,這是您應該如何做的。
class A
{
std :: vector <int> data;
A func();
};
A A::func()
{
A ret;
ret .data .assign (some_length, 123); // or whatever;
return ret;
}
由於復制省略,這可能會優化您想要的自動方式。 如果您認為編譯器不會刪除副本,請添加move構造函數。
A :: A (A && old)
: data (std :: move (old .data))
{
}
std::vector
的move構造函數將只復制指針。 如果你想知道如何工作的 ,以及這里的本土的同等學歷。
class A
{
int * data;
// Allocate
A (size_t size) : data (new int [size]) {}
// Free, only if we haven't moved.
~ A () {if (data) delete [] data;}
// Move
A (A && old) : data (old .data) {old .data = nullptr;}
A (const A &) = delete; // or implement with a new allocation.
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.