Нужно ли инициировать родительский класс или просто дочерний класс - PullRequest
0 голосов
/ 08 февраля 2019

Я новичок в программировании и анализирую код с родительским классом фруктов и дочерних классов яблок и груш.В этом примере есть указатель на родительский класс.После того, как я расширил этот код, я обнаружил, что используя объект, я могу получить доступ к родительским открытым членам и всем дочерним элементам.Вопрос в том, зачем мне эти указатели?

// are this pointer needed since I can use j.setWeight(11)

#include <iostream>

using namespace std;

class fruit {
private:
    int weight;

public:
    void setWeight(int x)
    {
        weight = x;
    }
    int getWeight()
    {
        return weight;
    }
};

class apple : public fruit {
public:
    void eat()
    {
        cout << "Now I am eating apple"
             << "=" << getWeight() << endl;
    }
};

class pear : public fruit {
public:
    void eat()
    {
        cout << "Now I am eating pear"
             << " = " << getWeight() << endl;
    }
};

int main()
{
    apple j;
    pear k;
    fruit* fruit1 = &j;
    fruit* fruit2 = &k;
    k.setWeight(5);
    k.eat();
    fruit1->setWeight(11);
    apple apple;
    apple.postaviTezinu(16);
    apple.jelo();

    return 0;
}

are this pointers needed since I can use j.setWeight(11) and results is same as 
fruit1 -> setWeight(11) ... what s difference, thx

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Я подозреваю, что код, который вы просматриваете, был написан для демонстрации того, как указатели на базовые классы могут использоваться с объектами производных классов.Нет, указатели не нужны для функциональности этого учебного упражнения.Фактически, это, вероятно, причина, по которой эта функциональность была выбрана.Поскольку вы видите, как выполнить то же самое без указателей, вам будет проще связать указатели с тем, что вы уже знаете.

Ключевые точки обучения, которые я вижу в этом упражнении:

  1. Один и тот же тип указателя (fruit *) может указывать на объекты разных типов (apple или pear).
  2. При использовании указателя на базовый класс вы можете получить доступ к членам базового класса.
  3. При использовании указателя на базовый класс вы не можете получить доступ к производным членам класса.(Подразумевается пропуском; сравните, что сделано с k с тем, что сделано с fruit1.)

Вам нужно будет перейти к более сложным урокам, чтобы учиться, когда указатели более полезнычем прямой доступ к объектам (вероятно, после того, как eat() превращен в виртуальную функцию).А пока просто изучите, как можно выполнить одну и ту же задачу разными способами.

(Конечно, вы можете получить эту информацию здесь, но этот код выглядит как часть серии. Продолжение этой серии может бытьлучший способ учиться.)

0 голосов
/ 08 февраля 2019

Поскольку вы новичок в программировании, изучение полиморфизма может быть немного продвинутым для вас на данном этапе.Чтобы ответить на ваш вопрос напрямую: Нет, вам не нужны указатели в вашем примере кода, и они ничем не полезны.

Однако указатели на объекты часто полезны для:

  • Сокращение ненужного копирования объектов
  • В случае полиморфизма (как в вашем примере) указатели помогают в разделах вашей программы, где вы не знаете, с каким типом объекта вы имеете дело, или нетхочу иметь с ними дело по-разному

Пример:

#include <iostream>
#include <vector>

class A
{
public:
    virtual void foo ()
    {
        std::cout << " I am A\n";
    }
};

class B : public A
{
public:
    virtual void foo ()
    {
        std::cout << " I am B\n";
    }
};

void bar ( const std::vector <A*> & obj )
{
    // Here it outputs the foo () function that is
    // appropriate for the class
    for ( unsigned int i = 0; i < obj . size (); ++i )
        obj [i] -> foo ();
}

int main ()
{
    A a1, a2, a3;
    B b1, b2, b3;

    // the below input style requires C++11,
    // otherwise input them one-by-one
    std::vector <A*> array {&a1, &b1, &a2, &a3, &b2, &b3};

    bar ( array );

    return 0;
}

Вышеупомянутый array может хранить любые объекты A, включая унаследованные (не можетсделать это без указателей);и функция bar все еще может выполнять операции с элементами в массиве, не нуждаясь в том, чтобы знать, к какому типу объекта они принадлежат в дереве наследования (из-за виртуальной функции).Это крайне важно для использования преимуществ полиморфизма и экономии на повторении функций и кода в целом.

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