-
Code:
class MyClass
{
public:
MyClass() { }
MyClass(const MyClass& rMyClass) { cout << "Copy constructor\n"; } // Copy constructor
MyClass& operator = (const MyClass& rMyClass) { cout << "Assignment operator\n"; return *this; }
};
void Help2(MyClass m)
{
}
int main()
{
MyClass a;
MyClass b;
a = b; // Invokes operator =
Help2(a); // Invokes copy constructor
}
There's a better example, I think.
-
I tried the following source code:
Code:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { cout <<"----------MyClass Constructor..."<<endl;} // constructor
MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;} // copy constructor
~MyClass() { cout <<"=======MyClass Destructor..." << endl;} // destructor
};
MyClass Function1 ()
{
cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
cout << "Nothing is returned" << endl;
}
int main()
{
cout << "I am going to create MyClass MyObject" << endl;
MyClass MyObject;
cout << "MyObject has just created" << endl << endl;
cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
Function1();
cout << endl << endl << endl << "We are back to main." << endl;
cout << "Zero is going to returned and exit main.." << endl;
return 0;
}
The Output is:
Code:
I am going to create MyClass MyObject
----------MyClass Constructor...
MyClass MyObject has just created
I am going to call the MyClass Function1 into the next line.
Ok, boss. This is inside the function1
Nothing is returned
=======MyClass Destructor...
We are back to main.
Zero is going to returned and exit main..
=======MyClass Destructor...
Analysis:
When I create a object, the constructor of the class is called.
When I call a object-oriented function without any arguments, none constructor is called.
When I exit from the this function, without returning a value or something, the destructor of the class is called.
When I eventually exit from int main() function, the destructor of the class is called once again.
So,
1) when you create an object, the constructor is called.
2) when you exit from any type (int, char, class, etc) of function, the destructor is called.Even if you haven't create an object in order to -in some way- activate the object oriented engine, the destructor is called.
So let's go further to my source code example number two.
Code:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { cout <<"----------MyClass Constructor..."<<endl;} // constructor
MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;} // copy constructor
~MyClass() { cout <<"=======MyClass Destructor..." << endl;} // destructor
};
MyClass Function1 (MyClass MyObject)
{
cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
cout << "Nothing is returned" << endl;
}
int main()
{
cout << "I am going to create MyClass MyObject" << endl;
MyClass MyObject;
cout << "MyObject has just created" << endl << endl;
cout << endl << "I am going to call the MyClass Function1 into the next line with an Object as an arguement." << endl;
Function1(MyObject);
cout << endl << endl << "We are back to main." << endl;
cout << "Zero is going to returned and exit main.." << endl;
return 0;
}
Output
Code:
I am going to create MyClass MyObject
----------MyClass Constructor...
MyClass MyObject has just created
I am going to call the MyClass Function1 into the next line with an Object as an arguement.
+++++++MyClass Copy Constructor...
Ok, boss. This is inside the function1
Nothing is returned
=======MyClass Destructor...
=======MyClass Destructor...
We are back to main.
Zero is going to returned and exit main..
=======MyClass Destructor...
Analysis:
When you call a class function with a class object as an argument, then the Copy Constructor is called. This is becauce
(by calling this function) there is another temporary copy of this class object into the stack.
So the copy constructor is called each time a temporary copy of the object is put on the stack.
Then when, the function exits, this temporary copy of the objects is destroyed, so the object's destructor is called.
Then the function exits, and the destructor is recalled.
Eventually the main() exits too, and the destructor is called for once last time.
No, let's delve it :P
Source Code Example Number 3
Code:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { cout <<"----------MyClass Constructor..."<<endl;} // constructor
MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;} // copy constructor
~MyClass() { cout <<"=======MyClass Destructor..." << endl;} // destructor
};
MyClass Function1 (MyClass MyObject)
{
cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
cout << "The copy of the Object is returned" << endl;
return MyObject;
}
int main()
{
cout << "I am going to create MyClass MyObject" << endl;
MyClass MyObject;
cout << "MyObject has just created" << endl << endl;
cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
Function1(MyObject);
cout << endl << endl << "We are back to main." << endl;
cout << "Zero is going to returned and exit main.." << endl;
return 0;
}
Output:
Code:
I am going to create MyClass MyObject
----------MyClass Constructor...
MyClass MyObject has just created
I am going to call the MyClass Function1 into the next line with an Object as an arguement.
+++++++MyClass Copy Constructor...
Ok, boss. This is inside the function1
The copy of the Object is returned
+++++++MyClass Copy Constructor...
=======MyClass Destructor...
=======MyClass Destructor...
We are back to main.
Zero is going to returned and exit main..
=======MyClass Destructor...
Analysis:
The output here is the same as the above, but...there are some details. This time, the function returns the object.
To make this happen, a copy of that object is re-made (the second) is the stack, so the copy constructor is called.
Am I right guys ?
-
Quote:
Originally Posted by
BlackSlash12
Am I right guys ?
Not quite.
For example 1:
Undefined behavior because you have declared that your function returns an object, but you never return one. You must return an a value (or object) of the specified type that you declared in a function.
Example two:
Undefined behavior.
Example 3:
Main creates a new object. Calls constructor.
Main calls function. New object is constructed. Copy constructor is invoked.
An object is being returned, so a new object is constructed. Copy constructor is invoked to copy argument into temporary object.
Temporary object & argument are both destructed. Both destructors are called.
Back in main, the class is destructed when it ends.
For two, you also seem confused that the destructor will be called twice, but since you never return an object, there's no temporary object to destruct. So it would get called only once, if the code should compile, that is.
In C++, you must return a value if your function specifies that it returns one.
-
Your first example is undefined behavior. Your function specifies a return value but doesn't actually return one. You can safely avoid any analysis attempt because the code is wrong and the effect you see is likely just a side effect of how the compiler implements proper code.
Your second example has the same problem.
The analysis on the third example is fine. Note that the output is slightly different than in example two. In the second example, there are only two constructor calls. In the third example, the only valid one, there are the same number of constructor and destructor calls.
-
Well I fixed the first example:
Code:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { cout <<"----------MyClass Constructor..."<<endl;} // constructor
MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;} // copy constructor
~MyClass() { cout <<"=======MyClass Destructor..." << endl;} // destructor
};
void Function1 (void)
{
cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
cout << "Nothing returned" << endl;
}
int main()
{
cout << "I am going to create MyClass MyObject" << endl;
MyClass MyObject;
cout << "MyObject has just created" << endl << endl;
cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
Function1();
cout << endl << endl << "We are back to main." << endl;
cout << "Zero is going to returned and exit main.." << endl;
return 0;
}
Compiled this time, sorry ....
Code:
I am going to create MyClass MyObject
----------MyClass Constructor...
MyClass MyObject has just created
I am going to call the MyClass Function1 into the next line with an Object as an arguement.
Ok, boss. This is inside the function1
Nothing is returned
We are back to main.
Zero is going to returned and exit main..
=======MyClass Destructor...
The example 3, I compiled it and I got --> 2 copy constructors and 3 destructors. Is this normal ? I think yes. The 2 copy constructors = 2 destructors + 1 destructor for main.
Elysia there is no other constructor. Just one an the start.
-
Well, your current example is fine, and you should get 1 constructor and one destructor.
-
>> Is this normal ? I think yes.
Yes. A copy constructor is still a constructor. There should be an equal number of constructors and destructors.
-
another way to avoid 2Copy Constructors and its 2Destructors:
Code:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { cout <<"----------MyClass Constructor..."<<endl;} // constructor
MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;} // copy constructor
~MyClass() { cout <<"=======MyClass Destructor..." << endl;} // destructor
};
MyClass *Function1 (MyClass *MyObject)
{
cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
cout << "Return Object" << endl;
return MyObject;
}
int main()
{
cout << "I am going to create MyClass MyObject" << endl;
MyClass MyObject;
cout << "MyObject has just created" << endl << endl;
cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
Function1(&MyObject);
cout << endl << endl << "We are back to main." << endl;
cout << "Zero is going to returned and exit main.." << endl;
return 0;
}
-
There is a big difference between passing by reference (which is what you're doing with the pointer) and passing by value (which is what you were doing before). You can't just change it like that to avoid a copy, because the meaning of the code changes.
To avoid a copy without changing the meaning of the code, you can usually use a reference to const to ensure that the object doesn't get changed.
Code:
const MyClass& Function1 (const MyClass& MyObject);
If it did get changed, and the function took the object by value, then changing it to a reference or pointer means that the original object is modified instead of the copy. That changes the entire meaning of the function, so you have to make that change only if you want to change the function's effects.
-
Well Daved, you have rights as always. I am reading this C++ book, and it reveals me slowly the secrets. Thanks man and thank all of you guys. I really appreciate your help and guideness.
Queries solved;
Topic Closed;