When passing an object to a method or function is the object then passed by reference or value when the object is not initiated by the new keyword?
My_object a;
my_function(a);
Is the object then passed to the function as a reference or a value?
void my_function(My_object a){
}
Or do I need to add & ?
void my_function(My_object &a){
}
The way an object is passed depends on the function's parameters and not on the way the object was created.
My_object a means it's passed by value.
For passing by reference you need to use My_object& a. If you do not intend to change the object, you may prefer const My_object& a. This will avoid accidental overwrite.
Related
I have a class whose objects have to pass a reference to themselves to another function.
I discovered that this is a pointer, not a reference. So how do I get the reference to the object that I'm in?
You can get an l-value of yourself to return as a reference by dereferencing the this pointer ie:
return *this;
Since this is a pointer to the object, you can get the object itself by derefrencing it with *this.
The function :
void func(MyClass& obj)
{ }
Calling the function.
func(*this);
I would like to clarify the differences between by value and by reference.
I drew a picture:
So, for passing by value, a copy of an identical object is created with a different reference, and the local variable is assigned the new reference, so to point to the new copy
How should I understand the following?
If the function modifies that value, the modifications appear also
within the scope of the calling function for both passing by value and by reference
I think much confusion is generated by not communicating what is meant by passed by reference. When some people say pass by reference they usually mean not the argument itself, but rather the object being referenced. Some other say that pass by reference means that the object can't be changed in the callee. Example:
struct Object {
int i;
};
void sample(Object* o) { // 1
o->i++;
}
void sample(Object const& o) { // 2
// nothing useful here :)
}
void sample(Object & o) { // 3
o.i++;
}
void sample1(Object o) { // 4
o.i++;
}
int main() {
Object obj = { 10 };
Object const obj_c = { 10 };
sample(&obj); // calls 1
sample(obj) // calls 3
sample(obj_c); // calls 2
sample1(obj); // calls 4
}
Some people would claim that 1 and 3 are pass by reference, while 2 would be pass by value. Another group of people say all but the last is pass by reference, because the object itself is not copied.
I would like to draw a definition of that here what i claim to be pass by reference. A general overview over it can be found here: Difference between pass by reference and pass by value. The first and last are pass by value, and the middle two are pass by reference:
sample(&obj);
// yields a `Object*`. Passes a *pointer* to the object by value.
// The caller can change the pointer (the parameter), but that
// won't change the temporary pointer created on the call side (the argument).
sample(obj)
// passes the object by *reference*. It denotes the object itself. The callee
// has got a reference parameter.
sample(obj_c);
// also passes *by reference*. the reference parameter references the
// same object like the argument expression.
sample1(obj);
// pass by value. The parameter object denotes a different object than the
// one passed in.
I vote for the following definition:
An argument (1.3.1) is passed by reference if and only if the corresponding parameter of the function that's called has reference type and the reference parameter binds directly to the argument expression (8.5.3/4). In all other cases, we have to do with pass by value.
That means that the following is pass by value:
void f1(Object const& o);
f1(Object()); // 1
void f2(int const& i);
f2(42); // 2
void f3(Object o);
f3(Object()); // 3
Object o1; f3(o1); // 4
void f4(Object *o);
Object o1; f4(&o1); // 5
1 is pass by value, because it's not directly bound. The implementation may copy the temporary and then bind that temporary to the reference. 2 is pass by value, because the implementation initializes a temporary of the literal and then binds to the reference. 3 is pass by value, because the parameter has not reference type. 4 is pass by value for the same reason. 5 is pass by value because the parameter has not got reference type. The following cases are pass by reference (by the rules of 8.5.3/4 and others):
void f1(Object *& op);
Object a; Object *op1 = &a; f1(op1); // 1
void f2(Object const& op);
Object b; f2(b); // 2
struct A { };
struct B { operator A&() { static A a; return a; } };
void f3(A &);
B b; f3(b); // passes the static a by reference
When passing by value:
void func(Object o);
and then calling
func(a);
you will construct an Object on the stack, and within the implementation of func it will be referenced by o. This might still be a shallow copy (the internals of a and o might point to the same data), so a might be changed. However if o is a deep copy of a, then a will not change.
When passing by reference:
void func2(Object& o);
and then calling
func2(a);
you will only be giving a new way to reference a. "a" and "o" are two names for the same object. Changing o inside func2 will make those changes visible to the caller, who knows the object by the name "a".
I'm not sure if I understand your question correctly. It is a bit unclear. However, what might be confusing you is the following:
When passing by reference, a reference to the same object is passed to the function being called. Any changes to the object will be reflected in the original object and hence the caller will see it.
When passing by value, the copy constructor will be called. The default copy constructor will only do a shallow copy, hence, if the called function modifies an integer in the object, this will not be seen by the calling function, but if the function changes a data structure pointed to by a pointer within the object, then this will be seen by the caller due to the shallow copy.
I might have mis-understood your question, but I thought I would give it a stab anyway.
As I parse it, those words are wrong. It should read "If the function modifies that value, the modifications appear also within the scope of the calling function when passing by reference, but not when passing by value."
My understanding of the words "If the function modifies that value, the modifications appear also within the scope of the calling function for both passing by value and by reference" is that they are an error.
Modifications made in a called function are not in scope of the calling function when passing by value.
Either you have mistyped the quoted words or they have been extracted out of whatever context made what appears to be wrong, right.
Could you please ensure you have correctly quoted your source and if there are no errors there give more of the text surrounding that statement in the source material.
I would like to clarify the differences between by value and by reference.
I drew a picture:
So, for passing by value, a copy of an identical object is created with a different reference, and the local variable is assigned the new reference, so to point to the new copy
How should I understand the following?
If the function modifies that value, the modifications appear also
within the scope of the calling function for both passing by value and by reference
I think much confusion is generated by not communicating what is meant by passed by reference. When some people say pass by reference they usually mean not the argument itself, but rather the object being referenced. Some other say that pass by reference means that the object can't be changed in the callee. Example:
struct Object {
int i;
};
void sample(Object* o) { // 1
o->i++;
}
void sample(Object const& o) { // 2
// nothing useful here :)
}
void sample(Object & o) { // 3
o.i++;
}
void sample1(Object o) { // 4
o.i++;
}
int main() {
Object obj = { 10 };
Object const obj_c = { 10 };
sample(&obj); // calls 1
sample(obj) // calls 3
sample(obj_c); // calls 2
sample1(obj); // calls 4
}
Some people would claim that 1 and 3 are pass by reference, while 2 would be pass by value. Another group of people say all but the last is pass by reference, because the object itself is not copied.
I would like to draw a definition of that here what i claim to be pass by reference. A general overview over it can be found here: Difference between pass by reference and pass by value. The first and last are pass by value, and the middle two are pass by reference:
sample(&obj);
// yields a `Object*`. Passes a *pointer* to the object by value.
// The caller can change the pointer (the parameter), but that
// won't change the temporary pointer created on the call side (the argument).
sample(obj)
// passes the object by *reference*. It denotes the object itself. The callee
// has got a reference parameter.
sample(obj_c);
// also passes *by reference*. the reference parameter references the
// same object like the argument expression.
sample1(obj);
// pass by value. The parameter object denotes a different object than the
// one passed in.
I vote for the following definition:
An argument (1.3.1) is passed by reference if and only if the corresponding parameter of the function that's called has reference type and the reference parameter binds directly to the argument expression (8.5.3/4). In all other cases, we have to do with pass by value.
That means that the following is pass by value:
void f1(Object const& o);
f1(Object()); // 1
void f2(int const& i);
f2(42); // 2
void f3(Object o);
f3(Object()); // 3
Object o1; f3(o1); // 4
void f4(Object *o);
Object o1; f4(&o1); // 5
1 is pass by value, because it's not directly bound. The implementation may copy the temporary and then bind that temporary to the reference. 2 is pass by value, because the implementation initializes a temporary of the literal and then binds to the reference. 3 is pass by value, because the parameter has not reference type. 4 is pass by value for the same reason. 5 is pass by value because the parameter has not got reference type. The following cases are pass by reference (by the rules of 8.5.3/4 and others):
void f1(Object *& op);
Object a; Object *op1 = &a; f1(op1); // 1
void f2(Object const& op);
Object b; f2(b); // 2
struct A { };
struct B { operator A&() { static A a; return a; } };
void f3(A &);
B b; f3(b); // passes the static a by reference
When passing by value:
void func(Object o);
and then calling
func(a);
you will construct an Object on the stack, and within the implementation of func it will be referenced by o. This might still be a shallow copy (the internals of a and o might point to the same data), so a might be changed. However if o is a deep copy of a, then a will not change.
When passing by reference:
void func2(Object& o);
and then calling
func2(a);
you will only be giving a new way to reference a. "a" and "o" are two names for the same object. Changing o inside func2 will make those changes visible to the caller, who knows the object by the name "a".
I'm not sure if I understand your question correctly. It is a bit unclear. However, what might be confusing you is the following:
When passing by reference, a reference to the same object is passed to the function being called. Any changes to the object will be reflected in the original object and hence the caller will see it.
When passing by value, the copy constructor will be called. The default copy constructor will only do a shallow copy, hence, if the called function modifies an integer in the object, this will not be seen by the calling function, but if the function changes a data structure pointed to by a pointer within the object, then this will be seen by the caller due to the shallow copy.
I might have mis-understood your question, but I thought I would give it a stab anyway.
As I parse it, those words are wrong. It should read "If the function modifies that value, the modifications appear also within the scope of the calling function when passing by reference, but not when passing by value."
My understanding of the words "If the function modifies that value, the modifications appear also within the scope of the calling function for both passing by value and by reference" is that they are an error.
Modifications made in a called function are not in scope of the calling function when passing by value.
Either you have mistyped the quoted words or they have been extracted out of whatever context made what appears to be wrong, right.
Could you please ensure you have correctly quoted your source and if there are no errors there give more of the text surrounding that statement in the source material.
I've been reading Myers book and came across the item on returning by reference/pointer vs by value.
The point is, if our function for example is like this:
ClassA& AddSomething(ClassA classA)
{
ClassA tempClassA;
//... do something on tempClassA
return tempClassA;
}
This would not work because we are returning a reference to a object that was created on the stack and it is dead now that the function is done.
He gives two solutions:
Using a local static ClassA inside the function. This has its
problems but atleast we can be sure that object exists.
Return as an object:
ClassA AddSomething(ClassA classA)
{
ClassA tempClassA;
//... do something on tempClassA
return tempClassA;
}
Now if I'm to do:
ClassA obj1;
ClassA obj2 = AddSomething(obj1);
My confusion now is, when executing this line:
A 'copy' of tempClassA is made and passed to the copy constructor
of ClassA (to initialize obj2)? OR
tempClassA is passed itself to the copy constructor of ClassA,
because copy constructor takes a reference.
So basically, whats passed to the copy constructor is a reference to tempClassA (which was created in stack inside the function) or a reference to a copy of tempClassA.
Also, another question I have is, I have read that if I get a reference of a function local variable, in that case the local variable will not be deleted.
For example,
ClassA & classRef = AddSomething(obj1);
In this case, if AddSomething() is returning a reference, then classRef not be pointing to a deleted reference because the local variable will be retained. Have I understood this correctly?
At worst, you're right: a copy of tempClassA is passed to the copy constructor. But compilers are allowed to eliminate that copy and construct the result in place form tempClassA. This is known as the "Return Value Optimization", or RVO. I don't know of a compiler that doesn't do this.
When an object is returned by value, there are two copies taking place: one from the local variable into the return value, and one from the return value into the target object. However, the implementation is allowed to elide one or both of these copies; this is called return value optimisation (RVO) in the first case, and copy elision in the second.
Object some_function() {
return Object(); // copy Object() into return value; candidate for RVO
}
Object another_function() {
Object obj;
return obj; // copy obj into return value; candidate for NRVO
}
Object result = some_function(); // copy return value into result; candidate for copy elision
The second function above is a candidate for a refinement type of RVO called named return value optimisation; the simplest form of RVO applies only to return statements that construct the return value inplace.
Regarding your second question, lifetime extension only applies to const references to objects returned by value; your code in the second question will not extend the lifetime of any object. See Returning temporary object and binding to const reference for more details.
You can never return a function local variable by reference. It would NOT work even if you used const reference to capture the returned value like this:
const ClassA& classRef = AddSomething(obj1);
Because if AddSomething returns a local object by reference, it'll be a dangling reference to a non-existing object by the time classRef gets to reference it.
I would like to clarify the differences between by value and by reference.
I drew a picture:
So, for passing by value, a copy of an identical object is created with a different reference, and the local variable is assigned the new reference, so to point to the new copy
How should I understand the following?
If the function modifies that value, the modifications appear also
within the scope of the calling function for both passing by value and by reference
I think much confusion is generated by not communicating what is meant by passed by reference. When some people say pass by reference they usually mean not the argument itself, but rather the object being referenced. Some other say that pass by reference means that the object can't be changed in the callee. Example:
struct Object {
int i;
};
void sample(Object* o) { // 1
o->i++;
}
void sample(Object const& o) { // 2
// nothing useful here :)
}
void sample(Object & o) { // 3
o.i++;
}
void sample1(Object o) { // 4
o.i++;
}
int main() {
Object obj = { 10 };
Object const obj_c = { 10 };
sample(&obj); // calls 1
sample(obj) // calls 3
sample(obj_c); // calls 2
sample1(obj); // calls 4
}
Some people would claim that 1 and 3 are pass by reference, while 2 would be pass by value. Another group of people say all but the last is pass by reference, because the object itself is not copied.
I would like to draw a definition of that here what i claim to be pass by reference. A general overview over it can be found here: Difference between pass by reference and pass by value. The first and last are pass by value, and the middle two are pass by reference:
sample(&obj);
// yields a `Object*`. Passes a *pointer* to the object by value.
// The caller can change the pointer (the parameter), but that
// won't change the temporary pointer created on the call side (the argument).
sample(obj)
// passes the object by *reference*. It denotes the object itself. The callee
// has got a reference parameter.
sample(obj_c);
// also passes *by reference*. the reference parameter references the
// same object like the argument expression.
sample1(obj);
// pass by value. The parameter object denotes a different object than the
// one passed in.
I vote for the following definition:
An argument (1.3.1) is passed by reference if and only if the corresponding parameter of the function that's called has reference type and the reference parameter binds directly to the argument expression (8.5.3/4). In all other cases, we have to do with pass by value.
That means that the following is pass by value:
void f1(Object const& o);
f1(Object()); // 1
void f2(int const& i);
f2(42); // 2
void f3(Object o);
f3(Object()); // 3
Object o1; f3(o1); // 4
void f4(Object *o);
Object o1; f4(&o1); // 5
1 is pass by value, because it's not directly bound. The implementation may copy the temporary and then bind that temporary to the reference. 2 is pass by value, because the implementation initializes a temporary of the literal and then binds to the reference. 3 is pass by value, because the parameter has not reference type. 4 is pass by value for the same reason. 5 is pass by value because the parameter has not got reference type. The following cases are pass by reference (by the rules of 8.5.3/4 and others):
void f1(Object *& op);
Object a; Object *op1 = &a; f1(op1); // 1
void f2(Object const& op);
Object b; f2(b); // 2
struct A { };
struct B { operator A&() { static A a; return a; } };
void f3(A &);
B b; f3(b); // passes the static a by reference
When passing by value:
void func(Object o);
and then calling
func(a);
you will construct an Object on the stack, and within the implementation of func it will be referenced by o. This might still be a shallow copy (the internals of a and o might point to the same data), so a might be changed. However if o is a deep copy of a, then a will not change.
When passing by reference:
void func2(Object& o);
and then calling
func2(a);
you will only be giving a new way to reference a. "a" and "o" are two names for the same object. Changing o inside func2 will make those changes visible to the caller, who knows the object by the name "a".
I'm not sure if I understand your question correctly. It is a bit unclear. However, what might be confusing you is the following:
When passing by reference, a reference to the same object is passed to the function being called. Any changes to the object will be reflected in the original object and hence the caller will see it.
When passing by value, the copy constructor will be called. The default copy constructor will only do a shallow copy, hence, if the called function modifies an integer in the object, this will not be seen by the calling function, but if the function changes a data structure pointed to by a pointer within the object, then this will be seen by the caller due to the shallow copy.
I might have mis-understood your question, but I thought I would give it a stab anyway.
As I parse it, those words are wrong. It should read "If the function modifies that value, the modifications appear also within the scope of the calling function when passing by reference, but not when passing by value."
My understanding of the words "If the function modifies that value, the modifications appear also within the scope of the calling function for both passing by value and by reference" is that they are an error.
Modifications made in a called function are not in scope of the calling function when passing by value.
Either you have mistyped the quoted words or they have been extracted out of whatever context made what appears to be wrong, right.
Could you please ensure you have correctly quoted your source and if there are no errors there give more of the text surrounding that statement in the source material.