I am studying reference of c++, and now I am quite confused by the difference between variable name and reference. The test code is below:
class TestClass{
private:
int num;
public:
TestClass(int n):num(n){
cout<<this<<" : init of : " <<this->num<<endl;
}
TestClass(const TestClass& t):num(t.num){
cout<<this<<" : copyInit of : " <<this->num<<endl;
}
};
int main(int argc, const char * argv[]){
TestClass t = *(new TestClass(55)); //just to test copy initialization
const TestClass t2 = TestClass(100); //option1
const TestClass &t2 = TestClass(100); //option2
}
So now I have two options in making object, which are exclusive with each other.
In my understanding, if I use options2, the compiler makes a temporary object in the stack memory and returns the reference value to t2.
If this is right, how can I verbalize or explain the option1? It seems that the same object is created in the stack memory and computer gives a name 't2' to that object, but I do not clearly understand how this option1 is different with the option2 because a name of variables and reference are somewhat confusing.
In addition, switching options alternatively, I could see that the objects are created in different memory locations in each case. (e.g. the object of option1 was created in 0x7fff5fbff828, and that or option2 was in 0x7fff5fbff820)
Could you please explain
1. what's the difference between a variable name(option1) and reference(option2).
2. how things work differently in option 1 and 2.
3. why objects are created in different memory location in either cases.
In advance, thanks for your help!
What is the difference between a name and a variable? The most obvious (based upon your first quote) difference is that a name is more general than a variable. Every variable has a name, but not every name is of a variable. There are also names of functions, classes, operators, and templates.
In Call by value, a copy of the variable is passed, whereas in Call by reference, a variable itself is passed. In Call by value, actual and formal arguments will be created in different memory locations, whereas in Call by reference, actual and formal arguments will be created in the same memory location.
A reference variable is a variable that points to an object of a given class, letting you access the value of an object. An object is a compound data structure that holds values that you can manipulate. A reference variable does not store its own values.
In computer programming, a variable or scalar is a storage location paired with an associated symbolic name (an identifier), which contains some known or unknown quantity of information referred to as a value.
const TestClass t2 = TestClass(100); //option1
const TestClass &t2 = TestClass(100); //option2
Option1:
calls the copy constructor of TestClass and passes in the temporary created on the right hand side of the "=". Copy elision eliminates unnecessary copying of objects (See Piotrs coment below).
Option 2:
You create 1 object, the temporary, which becomes bound to the reference.
- what's the difference between a variable name(option1) and reference(option2).
edit: I didn't know this before, but in actual fact there is not a second allocation in option 1 (Thanks Piotr) this is due to copy elision which refers to a compiler optimization technique that eliminates unnecessary copying of objects.
To use your words, the "variable name" is a block of memory that contains data. The reference is like a pointer in the sense that it points to another "variable name", but it must be initialised, and is never null.
- how things work differently in option 1 and 2.
As Others have said option 1 is a static type, where as option 2 could point to an instance of a derived (from TestClass) object.
- why objects are created in different memory location in either cases.
Despite being "identical" TestObjects(100) they are individual instances and therefore in different memory (addresses)
1)what's the difference between a variable name(option1) and reference(option2).
Name has static type. Reference can be bind to derived classes - we do not know the exact type of referred objects.
In your very example - for option 2 - you extended the lifetime of temporary object by creating const reference to it - see http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself, and thus avoids what would otherwise be a common dangling-reference error.
2)how things work differently in option 1 and 2.
If you call virtual function - then for variable name you know which function will be called, for references - you cannot know in more complicated example than yours.
3)why objects are created in different memory location in either cases.
They are different objects, they life in the same time - so why their memory location should be identical?
Other difference is that for option 1 you created automatic variable, for option 2 it is temporary variable - both might use different memory (stack vs. registers or some reserved memory just for temporaries)
Consider more complicated example:
class TestClass{
protected:
int num;
public:
TestClass(int n):num(n){
cout<<this<<" : init of : " <<this->num<<endl;
}
TestClass(const TestClass& t):num(t.num){
cout<<this<<" : copyInit of : " <<this->num<<endl;
}
virtual void printNum () const { cout << "NUM: " << num << endl; }
};
class TestClassDerived : public TestClass {
public:
TestClassDerived(int n):TestClass(n){}
virtual void printNum () const { cout << "DERIVED NUM: " << num << endl; }
};
int main(int argc, const char * argv[]){
const TestClass t1 = TestClass(100); //option1
const TestClass &t2 = TestClassDerived(100); //option2
t1.printNum();
t2.printNum();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With