Sample code:
MyItemType a;
MyItemType b;
a.someNumber = 5;
b = a;
cout << a.someNumber << endl;
cout << b.someNumber << endl;
b.someNumber = 10;
cout << a.someNumber << endl;
cout << b.someNumber << endl;
The output:
5
5
5
10
If a and b were reference types, the last 2 lines would have been 10 and 10 instead of 5 and 10 I guess.
Does this mean when you do a declaration like this:
AClassType anInstance;
it is treated like a value type?
------Here is MyItemType.h------------
#ifndef MYITEMTYPE_H
#define MYITEMTYPE_H
class MyItemType{
public:
int someNumber;
MyItemType();
};
MyItemType::MyItemType(){
}
#endif /* MYITEMTYPE_H */
It is not treated like a value type, in fact it is.
While in Java object variables store references to objects, in C++ there is an important difference between an object and its reference. Assignment is by default really by value.
If you want a variable to be just a reference, you use either a reference or a pointer type, depending what you want to with it. These types are declared
T*
andT&
.To illustrate this a little more:
In Java, when you say
MyClass obj
, an object is created, but a reference/pointer is stored in the variableobj
.In C++,
MyClass obj
creates the object and will stored it inobj
. If you want to work with references/pointers, you need to declare variables explicity asMyClass* objPointer
orMyClass& objReference
.In C++ objects are referred to as static (stack) variables when they are created without a pointer reference. Dynamic (heap) variables are pointer references that require manual memory management.
In Java or C#, by contrast, almost all objects are reference types which behave like pointers except they are garbage collected whereas value types are a special subset of all objects that are generally immutable. (C++ stack variables are certainly not immutable).
The short explanation is in this key part
you are using the copy assignment operator, meaning this sign here
=
.the default behaviour of this operator is to apply a memberwise copy, so if you don't define/overload your own operator this row will copy all the values stored in all the members of
a
in the corresponding members ofb
.the
new
operator it's a complete different story, it's often used to allocate objects on the heap and managing them with a pointer avoiding the stack and unnecessary copies.While C++ does not call objects value or reference types, the behaviour of value and reference types has equivalence in C++.
Given two objects
a
andb
,a = b
:b
intoa
keeping them separate objects;b
intoa
, making them refer to the same object.For C++:
Pointers/references may be to value objects, objects allocated by
new
or some other memory management scheme (e.g.malloc
or the Win32CoTaskMalloc
).Basically, yes (if you consider the C++ equivalent to mean the same as in Java).
AClassType anInstance;
is an object, not a reference.MyItemType a
andMyItemType b
are different objects, they reside in different memory space, so obviously changes to one won't affect the other.When you do
a=b
, you don't reference one object with the other, but, in this case, do a member-wise assignment. It's basically like sayingBy default, C++ treats its classes as value types and makes deep (element-wise) copies.
But you can store your member variables inside the class in free storage (on the heap) and customize (override) the behaviour of the assignment-operator (b = a in your code) to show the behaviour of a reference type.
This (and some other 'tricks') is for the example, how the shared_ptr smart pointer is designed. It is a C++ class, where each instance references the same original data, regardless how often it is copied.