Reputation: 3978
I have always assumed that passing variables with [pass-by-value] in [c++], makes a copy of them, and so the function receiving these copies can not change the original variable's content.
I guess it is because when argument is passed by value, [copy-constructor] is called, and if it is not overridden by the programmer, the default [copy-constructor] does [shallow-copy] instead of [deep-copy]!
So my question is that why they called it pass-by-value, while in the case of having pointers in the class, the function has access to the reference of that pointer and can damage it. Also is this conclusion correct? "Whenever have pointers in the class, and you might pass an object of that class by value as a function argument, define the copy constructor!"
If this error is famous, does anyone know the name or phrase to this problem?
Below is my code that resulted in a modified list. Objects of this class contain an int member variable as well as a pointer to a list of nodes member variable.
class ComplicatedObject{
public:
ComplicatedObject();
~ComplicatedObject();
//ComplicatedObject(const ComplicatedObject& c); // copy construtor
//ComplicatedObject& operator=(const ComplicatedObject& c); // =operator
int int_member_varialbe_; // an int member variable
void addToList(int d);
void printList();
private:
struct node{
int data;
node* next;
};
node* head_; // points to the beginning of a list (linkedlist of int)
};
The below code prints 2. And then prints 2 3 !
Test.cpp:
void myfunction(ComplicatedObject obj){
obj.addToList(3);
obj.int_member_variable_ = 5;
}
int main(void){
ComplicatedObject c_object;
c_object.addToList(2);
c_object.printList(); //prints 2
cout << "int member variable befor passing:";
cout << c-object.int_member_variable_ << endl; //prints 6 (a default value)
myfunction(c_object); //pass-by-value
cout << "int member variable after passing:";
cout << c-object.int_member_variable_ << endl; // prints 6 (not 5)
c_object.printList(); // prints 2 3 ! List get changed!
return 0;
}
Upvotes: 0
Views: 993
Reputation: 122489
I have always assumed that passing variables with [pass-by-value] in [c++], makes a copy of them, and so the function receiving these copies can not change the original variable's content.
Yes, that's true.
I guess it is because when argument is passed by value, [copy-constructor] is called, and if it is not overridden by the programmer, the default [copy-constructor] does [shallow-copy] instead of [deep-copy]!
A "copy" is a "shallow copy". A "copy" copies all the contents of the objects. And the contents are the fields. And if the field is a pointer, then the content is the pointer, the address. That's it.
So my question is that why they called it pass-by-value, while in the case of having pointers in the class, the function has access to the reference of that pointer and can damage it.
So? The things that those pointers point to are not part of the object. So it's irrelevant. The pointer is what's part of the object.
Upvotes: 1
Reputation: 24850
So my question is that why they called it pass-by-value, while in the case of having pointers in the class, the function has access to the reference of that pointer and can damage it.
Let's consider the following situation:
int func(int b, int* c)
{
/* some stuff */
}
for the first parameter, b
, it is a "ByVal" delivery, so what the compiler usually does is
sizeof(int)
space for b
b
to the spacefunc
can modify the local copy of b
without affecting original b
This is necessary, since if it is automatically delivered "ByRef", compiler will meet trouble when non L-value is given, i.e. 1, as you cannot get the reference from a constant value.
Now let's see what happens to c
. Again, it has a type of int*
, not a int&
, so it is treated the same way like int b
.
However when c
is a int*
pointer, it does not store any other data except the address to some object with type int
. So indirect access via the pointer is permitted and there is only copy of the address but not the value it points to,thus can be damaged.
Upvotes: 0
Reputation: 6031
You are correct. A shallow copy (which occurs if your class lacks a copy constructor) copies the pointers in your class, but not what they point to. You must define a copy constructor which performs a deep copy if you'd like to be able to properly pass a non-const object by value.
Upvotes: 2