Instantiating Objects On The Heap

With reference to Method 1 and Method 2 in main() my question is below:

Question: how does 1) instantiating an object on the heap, and then afterwards also allocating chunks of memory from the heap for the objects individual data members, compare to 2) Not instantiating on the heap, but still allocating chunks of memory from the heap for data members.

I understand how: Enemy* pBadGuy = new Boss(); works with respect to pointing pBadGuy to the new chunk of memory allocated for the Boss object, and then deleting the memory and setting the pointer to zero when the function ends, but I don’t understand how an instantiated new Boss as a whole object on the heap, compares (in terms of its existance on the heap as a whole object) to allocated chunks of memory from the heap for the individual data members.

Edit: I've been tempted to think if an object is instantiated on the heap, then why aren't all the data members automatically on the heap without having to assign them with "new". Also when applying delete to the pointer pBadGuy, why doesn't this destroy the whole object, Or does it. I'm confused!

Many Thanks, Gary.

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
73
74
75
76
77
78
79
80
81
82
83
84
85
//Polymorphic Bad Guy
//Demonstrates calling member functions dynamically

#include <iostream>

using namespace std;

class Enemy
{
public:
    Enemy(int damage = 10);
    virtual ~Enemy();
    void virtual Attack() const;	
    
protected:
    int* m_pDamage;
};

Enemy::Enemy(int damage)  // Class Enemy
{
    m_pDamage = new int(damage);
}

Enemy::~Enemy()               
{
    cout << "In Enemy destructor, deleting m_pDamage.\n";
    delete m_pDamage;
    m_pDamage = 0;
}

void Enemy::Attack() const
{
    cout << "An enemy attacks and inflicts " << *m_pDamage << " damage points.";
}  

class Boss : public Enemy  // Class Boss
{
public:
    Boss(int multiplier = 3); 
    virtual ~Boss();
    void virtual Attack() const;
    
protected:
    int* m_pMultiplier; 
};

Boss::Boss(int multiplier)
{
    m_pMultiplier = new int(multiplier);
}

Boss::~Boss()                 
{
    cout << "In Boss destructor, deleting m_pMultiplier.\n";
    delete m_pMultiplier;
    m_pMultiplier = 0;
} 

void Boss::Attack() const
{
    cout << "A boss attacks and inflicts " << (*m_pDamage) * (*m_pMultiplier)
         << " damage points.";
}

int main()
{
    // Method 1 (As Per Book)
    cout << "Calling Attack() on Boss object through pointer to Enemy:\n";
    Enemy* pBadGuy = new Boss();  // Instantiate On The Heap !!!
    pBadGuy->Attack();

    cout << "\nDeleting pointer to Enemy:\n";
    delete pBadGuy;
    pBadGuy = 0;
	
    // Method 2 (My Test) 
    Boss test;  // Not Instantiated On The Heap !!!
    cout << "\nCalling Attack() on Boss object through pointer to Enemy:\n";
    Enemy* pBadGuy2 = &test;
    pBadGuy2->Attack();

    cout << endl;
   
    return 0;
}
Last edited on
You forgot your question. What do you want to "compare"?

if an object is instantiated on the heap, then why aren't all the data members automatically on the heap without having to assign them with "new"
They are. Your manual memory management makes them to be allocated in different heap area.

when applying delete to the pointer pBadGuy, why doesn't this destroy the whole object,
It does. Why do you think it does not?
Last edited on
Thanks MiiNiPaa,

I'm really trying to get this, so thank you for helping.

Point 1)

They are. Your manual memory management makes them to be allocated in different heap area.

Why then is this required
m_pMultiplier = new int(multiplier);

if the data members are automatically on the heap from
Enemy* pBadGuy = new Boss(); // Instantiate On The Heap !!!


Point 2)

I didn't realise until now that using delete calls the destructor. I was thinking the destructor only got called when objects were destroyed by going out of scope when the function they were instantiated in ends. I'll have a think about this point 2 a bit later when I get back from work in about 8 hours.

Thanks again :)

Why then is this required
Because m_pMultiplier is a pointer. So you need to make it point to the valid place. If you would take address of variable in constructor, you can point m_pMultiplier to stack variable just as easy.

Note that m_pMultiplier itself is placed where object is located: on heap in first case, and on stack n second.
pBadFuy itself is created on stack. But you make it point to the unnamed object crated on heap.

Fantastic answer MiiNiPaa, thank you very much, as that seems to answer my initial question very well indeed :)

Just one more question about my own example below. In the program below, does object2's data member object1B have its data members: valueA valueB check1 check2 stored on the heap, since object2 was instantiated on the heap?

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
// My example program!

#include <iostream>

using namespace std;

class One
{
public:
    One(): valueA(5) {};
    int valueA;
    int valueB;
    bool check1;
    bool check2;
};

class Two
{
public:
    ~Two() {cout << "In Destructor Doing Nothing\n";};
    One object1B;
};

int main()
{
    One object1A;  // Instantiate on the stack!
    cout << object1A.valueA << endl;

    Two* object2 = new Two;  // Instantiate on the heap!
    cout << object2 -> object1B.valueA << endl;
    delete object2;
    object2 = 0;

    return 0;
}
Last edited on
Yes.
Cool. Thanks again.
Topic archived. No new replies allowed.