Hello,
I’ve been playing around a bit with functions returning a class object. There’s one situation where I don’t quite follow what’s happening:
I’ve written the function do_something that creates a class object, assigns it some value and then returns that object. Please see code below.
Since I’m returning by value I would have expected the original, local, ‘c’ to be destroyed and a copy of it to be returned. If so, for the code below, I should see something like:
Default constructor called. (for ‘c’ in do_something)
Destructor called. (when the local c in do_something goes out of scope)
Copy constructor called. (when ‘c1’ in main is initialized with the copy of ‘c’)
Length: 4, Width: 3. (for << c1 in main)
I just called do_something. (also in main)
Length: 4, Width: 3. (for c1.print in main)
Destructor called. (when ‘c1’ in main goes out of scope)
Instead I get:
Default constructor called.
Length: 4, Width: 3.
I just called do_something.
Length: 4, Width: 3.
Destructor called.
Can you see where my thinking is going wrong? What happens (in the program/with memory) when do_something returns c?
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
#include <iostream>
class class1{
private:
int* length;
int* width;
public:
class1(){
length = new int(0);
width = new int(0);
std::cout << "Default constructor called." << std::endl;
}
class1(const class1& c){
length = new int(*(c.length));
width = new int(*(c.width));
std::cout << "Copy constructor called." << std::endl;
}
class1& operator= (const class1& c){
*length = *(c.length);
*width = *(c.width);
std::cout << "Assignment operator called." << std::endl;
return *this;
}
~class1(){
delete length;
delete width;
std::cout << "Destructor called." << std::endl;
}
void print() const{
std::cout << "Length: " << *length << ", Width: " << *width << "." << std::endl;
}
void set_values(int l, int w){
*length = l;
*width = w;
}
};
std::ostream& operator<<(std::ostream& os, const class1& c){
c.print();
return os;
}
class1 do_something(int length, int width){
class1 c;
c.set_values(length, width);
return c;
}
int main()
{
class1 c1 = do_something(4,3);
std::cout << c1 << "I just called do_something." << std::endl;
c1.print();
// calls, as expected, default constructor, copy constructor, destructor, destructor
/*class1 c1;
class1 c2 = c1;*/
// calls, as expected, default constructor (2x), assignment operator, destructor (2x)
/*class1 c1;
class1 c2;
c1 = c2;*/
}
|