Классы и указатели, как они работают? - PullRequest
0 голосов
/ 02 февраля 2012

Основная проблема заключается в создании динамического класса. Что я сделал:

ptr = new animal[2];

Я пытаюсь создать динамический массив размера 2, на который указывает указатель ptr. Проблема возникает, когда я пытаюсь выполнить следующие операции:

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

Я использую отладчик DDD (графический интерфейс gdb), и когда я отображаю ptr, я вижу только указатель на один объект. Когда я пытаюсь установить скорость, первый, кажется, работает, а второй - нет (скорость по умолчанию равна 0). Печать только мусор.

Я не совсем уверен, что происходит, пожалуйста, помогите.

Также, когда я делаю:

ptr->print();

Предполагается, что он будет печататься как для ptr[0], так и для ptr[1], или просто для ptr[0]?

Кроме того, может ли кто-нибудь быстро нарисовать картину того, как ptr и новый динамический класс выглядят? На мой взгляд, это ptr, указывающий на массив, размер массива два, у каждого есть объект животного.

#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;
    }

Ответы [ 4 ]

6 голосов
/ 02 февраля 2012

вместо

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

Вы можете использовать более интуитивный и даже более правильный

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

Когда вы делаете ++, вы меняете значение ptr, поэтому оно будет указывать на следующий элемент. Вы должны сохранить указатель на начало массива, чтобы потом [] удалить его.

Кроме того, ptr ++ увеличивает указатель, но возвращает значение old . Возможно, вы хотели (++ ptr) -> setspeed (13), который будет увеличивать и использовать значение new в остальной части выражения.

Что касается вашего другого вопроса, ptr->print() - это то же самое, что и ptr[0].print(), а (ptr+1)->print() - это то же самое, что и ptr[1].print(). Нет встроенного синтаксиса для вызова print() для всех элементов.

6 голосов
/ 02 февраля 2012

Хорошо, кто-то уже указал на проблему утечки памяти .

Итак, вы выделили массив из двух животных (ptr = new animal [2];) и сохранили указатель на первое в ptr.

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

(я игнорирую position_x и position_y ради космоса)

Затем вы устанавливаете скорость первого на 9 (ptr[0].setspeed(9);):

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

Тогда вы делаете что-то очень странное.

ptr++->setspeed(13);

Зачем ты это делаешь, я не знаю. Не делай этого. Я не шучу. Я могу понять, что означает этот код, но я бы никогда не написал что-то подобное. Он служит только для того, чтобы сеять замешательство.

Но давайте представим, что какое-то время это нормальное занятие ... ptr++ увеличивает указатель и возвращает старое значение.

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

... а затем устанавливает скорость животного, на которое указывает этот результат, равным 13.

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

Наконец, ptr->print() печатает животное, обозначенное ptr, которое является вторым.

5 голосов
/ 02 февраля 2012

Мой с ++ ржавый, но вот что я думаю:

    ptr++->setspeed(13);

Это постинкремент. ptr сначала оценивается , а затем увеличивается. Это означает, что setspeed вызывается для исходного значения указателя.

Лично я считаю, что этот стиль кода неприемлем, и я бы уволил любого, кто это написал. Это трудно читать, и это должно быть легко читать и понимать.

0 голосов
/ 02 февраля 2012

Если оператор ++ находится после переменной (ptr ++), он сначала выполняет оценку, а затем увеличение. Значит это утверждение

ptr++->setspeed(13);

работает как

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

А ++ ptr-> setspeed (13) будет работать противоположным образом.

Теперь вы можете увидеть, где проблема. На самом деле вы вызываете setspeed (13) для animal [0] и вызываете print () для animal [1].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...