Rave
Rave

Reputation: 843

Classes and Pointers, how do they work?

The main issue is with creating a dynamic class. What I did:

ptr = new animal[2];

I'm trying to create a dynamic array of size 2, pointed by the pointer ptr. The issue arises when I try these operations:

ptr[0].setspeed(9);
ptr++->setspeed(13);

I am using DDD (gdb graphical) debugger and when I display ptr, I only see it pointing to one object. When I try to set the speed, the first one seems to work, but the second one won't (the speed is on the default of 0). Printing only gets garbage.

I am not so sure what's going on, please help.

Also when I do:

ptr->print();

Is it supposed to print for both ptr[0] and ptr[1], or just ptr[0]?

Also, can someone quickly draw a picture of how the ptr and new dynamic class look like? The way I see it, it is a ptr pointing to an array, array size of two, each one has an animal object.

#include <iostream>
using namespace std;

class animal
{
    private:
        int speed;
        double position_x;
        double position_y;

   public:
        animal() : speed(0), position_x(0), position_y(0)
        {
        }

        animal (int v, double x, double y)
        {
            this->speed = v;
            this->position_x = x;    
            this->position_y = y;
        }

        animal(const animal & g)
        {
            this->speed = g.speed;
            this->position_x = g.position_x;  
            this->position_y = g.position_y;
        }

        ~animal();

        void print();

        int getspeed() { return this->speed; }

        int getx() { return this->position_x; }

        int gety() { return this->position_y; }

        void setspeed(int s) { this->speed = s; }
   };

    void animal::print()
    {
        cout << "speed: " << this->getspeed() << endl;
        cout << "position_x: " << this->getx() << endl;
        cout << "position_y: " << this->gety() << endl;
    }

    int main()
    {
        animal *ptr;
        ptr = new animal;
        ptr = new animal [2];

       ptr[0].setspeed(9);
       ptr++->setspeed(13);

       ptr->print();
       cout << ptr[0].getspeed() << endl;
       cout << ptr[1].getspeed();

       return 0;
    }

Upvotes: 0

Views: 198

Answers (4)

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234664

Ok, someone pointed out the memory leak issue to you already.

So, you have allocated an array of two animals (ptr = new animal [2];), and stored a pointer to the first one in ptr.

+----------+----------+
| speed: 0 | speed: 0 |
+----------+----------+
     ^
     |
     |
    ptr

(I'm ignoring the position_x and position_y, for the sake of space)

Then you set the speed of the first one to 9 (ptr[0].setspeed(9);):

+----------+----------+
| speed: 9 | speed: 0 |
+----------+----------+
     ^
     |
     |
    ptr

Then you do something very weird.

ptr++->setspeed(13);

Why you do this, I don't know. Don't do this. I'm not joking. I can figure out what this code means, but I would never write something like this. It only serves to sow confusion.

But let's pretend it is a sane thing to do for a while... ptr++ increments the pointer, and returns the old value.

+----------+----------+
| speed: 9 | speed: 0 |
+----------+----------+
      ^          ^
      |          |
      |          |
    result      ptr
   of ptr++

... and then it sets the speed of the animal pointed by that result to 13.

+-----------+----------+
| speed: 13 | speed: 0 |
+-----------+----------+
      ^          ^
      |          |
      |          |
    result      ptr
   of ptr++

Finally, ptr->print() prints the the animal pointed by ptr, which is the second one.

Upvotes: 6

Fan Zhang
Fan Zhang

Reputation: 19

If the ++ operator is after the variable(ptr++), it will first does the evaluation and then the increment. It means this statement

ptr++->setspeed(13);

works as

ptr->setspeed(13)  // ptr point to animal[0]
ptr++              // ptr point to anima[1] after this statement

And ++ptr->setspeed(13) will work in opposite way.

Now you can see where the problem is. You actually call setspeed(13) on animal[0], and the call print() on animal[1].

Upvotes: 0

marcus
marcus

Reputation: 5199

Instead of

ptr[0].setspeed(9);
ptr++->setspeed(13);

You could use the more intuitive and even more correct

ptr[0].setspeed(9);
ptr[1].setspeed(13);

When you do a ++, you are changing the value of ptr, so it will point to the next element. You should keep a pointer to the start of the array so you can delete[] it later.

Also, ptr++ increments the pointer but returns the old value. Maybe you wanted (++ptr)->setspeed(13), which will increment and use the new value in the rest of the expression.

As for your other question, ptr->print() is the same as ptr[0].print(), and (ptr+1)->print() is the same as ptr[1].print(). There is no built-in syntax to call print() on all elements.

Upvotes: 6

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230521

My c++ is rusty, but here's what I think:

    ptr++->setspeed(13);

This is a post-increment. ptr is first evaluated and then incremented. Meaning that setspeed is called on the original value of the pointer.

Personally, I think that this style of code is unacceptable and I'd fire anyone who writes this. It's hard to read and it should be easy to read and understand.

Upvotes: 5

Related Questions