Construction, address and value of private variable

Hi All! I am having some troubles of understanding C++ vairable lifecycles.

I wrote a tiny application(1) to understand it, but it only complicates the things:

1. when Holder object constructed - it's private variable is automatically constructed. Is there any way not to let it be constructed?

2. just after constructing Holder I am checking address of private variable, and for example it's 20. Then I am checking address of parameter (reference of the same type) and it's 40. Then I am assigning parameter to local variable and checking local variable address - and it's still 20, but it contains real value of parameter. Explain me please how is it possible, it is not copied over to the same address because copy constructor would print it.

(1):
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
#include <iostream>

static int count = 0;

class Item {
public:
    Item() {
        number = ++count;
        std::cout << "Item default constructor " << number << '\n';
    }
    Item(const Item& item) {
        number = ++count;
        std::cout << "Item copy constructor " << number << '\n';
    }
    ~Item() {
        std::cout << "Item descructor\n";
    }

    void printNumber() {
        std::cout << "number: " << number << '\n';
    }

    void setNumber(int n) {
        number = n;
    }

private:
    int number;
};

class Holder {
public:
    Holder() {}

    Holder(Item& item) {
        std::cout << "constructing holder\n";
        item.printNumber();
        m_item.printNumber();
        std::cout << "m_item: " << &m_item << '\n';
        std::cout << "item: " << &item << '\n';
        m_item = item;
        m_item.printNumber();
        std::cout << "m_item: " << &m_item << '\n';
        std::cout << "setting number\n";
        item.setNumber(50);
        item.printNumber();
        m_item.printNumber();
        Item i = item;
        std::cout << "i: " << &i << '\n';
        m_item = i;
        std::cout << "m_item: " << &m_item << '\n';
        std::cout << "end holder construct\n";
    }

private:
    Item m_item;
};

int main(int argc, char *argv[]) {

    std::cout << "constructing:\n";
    Item item;
    std::cout << &item << '\n';

    Holder holder(item);

    return 0;
}


Application output:
constructing:
Item default constructor 1
0x7fffbea49c10
Item default constructor 2
constructing holder
number: 1
number: 2
m_item: 0x7fffbea49c00
item: 0x7fffbea49c10
number: 1
m_item: 0x7fffbea49c00
setting number
number: 50
number: 1
Item copy constructor 3
i: 0x7fffbea49bc0
m_item: 0x7fffbea49c00
end holder construct
Item descructor
Item descructor
Item descructor
Last edited on
1. No, there isn't. However, you can make m_item a pointer and create an Item instance later when you need it. In that case don't forget to delete it in the destructor.
2. Because when you write m_item = item, the assignment operator (operator=) will be invoked, not the copy constructor. The default assignment operator creates a bitwise copy of the object, just like the default copy constructor.
There is a rule that's generally called "Law of the Big Three", see:
http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29

You should add something like this to Item:
1
2
3
4
5
const Item& operator=(const Item& item) {
        number = item.number;
        std::cout << "Item assignment operator " << number << '\n';
        return *this;
    }
Athar, thanx for your reply, now I really understand how it's working!
Topic archived. No new replies allowed.