An example:
class A
{
....
A func();
};
A A::func()
{
...
return something;
}
At assembly level, when compiled, the function A::func
will actually have two parameters: the first one is the this
pointer, and the second one is the address of a temp A
object, created by the caller to store the return value.
For example, if we write a.func()
, the program will create a temp A
object (let's call it t
) in the stack, and pass the address of a
as first parameter, the address of t
as second parameter, finally call the function func
.
Here is my question: in the realization of A::func
, we can get the address of a
- it's the pointer this
; but do we have a way to get the address of t
? What's its name?
It will be useful to have it if, for example, I would like to do some memory alloc/free before returning the result.
Here is an example of what I want to do:
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;
}
Of course, I can create a local object in A::func
and then return it; but then the program will do a copy between my local object and the temp object created by the caller. Since the caller already created a temp object, I'm hoping that I can save both time and space by just using it directly. Is that possible?
Well this is maybe out of c++, but I'm still hoping...
There is no such a temp A
object parameter ( t
) in the stack.
If you call A a1 = a.func();
and return something;
inside, the copy constructor
will be called, equivalent to this A a1(something);
. The a1
and something
are different instances.
If you A a1; a1 = a.func();
A a1; a1 = a.func();
and return something;
inside, the a1 = something; // (operator =)
a1 = something; // (operator =)
will be called. The a1
and something
are different instances.
If you call A a1 = a.func();
and return A(p1);
inside, this is equivalent to A a1(p1);
, there is one instance a1
.
If you call a.func();
directly without assigning to a var and return something;
inside, nothing happens when return.
If you call a.func();
directly without assigning to a var and return A(p1);
inside, a temp object will be constructed and then destroyed immediately.
If you A a1; a1 = a.func();
A a1; a1 = a.func();
and return A(p1);
inside, a temp object will be constructed, and then operator= will be called a1 = temp object;
and then the temp object will be destroyed.
For your reference.
After all, A a1 = a.func()
or A a1; a1 = a.func()
A a1; a1 = a.func()
, return something; // a var
return something; // a var
or return A(p1); // call constructor
return A(p1); // call constructor
will cause different behaviors, I think you can control memory correctly.
The supplying of &a
to func
is a form of copy elision .
There is no guarantee that will happen at all, and no C++ level access to the implementation.
I don't think you're clear in your own head when you say "I would like to do some memory alloc/free before returning the result", can you give a specific example? Probably everything you need is made possible by copy elision, move operators, and RAII.
Responding to your example, here's how you should do it.
class A
{
std :: vector <int> data;
A func();
};
A A::func()
{
A ret;
ret .data .assign (some_length, 123); // or whatever;
return ret;
}
This will probably optimise the way you want automatically due to copy elision. If you think the compiler won't elide the copy, add a move constructor.
A :: A (A && old)
: data (std :: move (old .data))
{
}
std::vector
's move constructor will simply copy the pointer. If you want to know how that works, well here's the homegrown equivalent.
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.
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.