Если базовый класс имеет закрытые члены-данные, которые изменены в функции-члене, как производный класс использует эту функцию? - PullRequest
0 голосов
/ 11 февраля 2019

Я работаю над проектом, чтобы узнать об объектно-ориентированном программировании.Из того, что я понимаю, когда класс является производным от базового класса, он может получить доступ ко всем открытым функциям-членам базового класса.В C ++ публичное наследование означает, что частные члены не могут быть доступны.Так что же происходит, когда закрытая функция-член изменяется в базовом классе?

Я пытался создать несколько тестовых программ, чтобы увидеть, что происходит, но я все еще в замешательстве.Я также попытался посмотреть онлайн, чтобы увидеть, смогу ли я найти какие-либо ответы, но я действительно не нашел ни одного.

class Base 
{
    private:
        int length;
    public 
        void increaseLengthByOne();
};

void Base::increaseLengthByOne()
{
    this->length++;
}

class Derived : public Base 
{
    private:
        int dLength;
    public: 
        void newFunction();
};

void Derived::newFunction()
{
    printf("New function working");
    increaseLengthByOne();
}

Насколько я понимаю, длина не будет изменена, а длина не может быть изменена.Что же тогда делает функция incrementLengthByOne?И как бы я сделать так, чтобы функция увеличения длины могла увеличить длину?

Ответы [ 5 ]

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

Из того, что я понимаю, ... Длина не может быть изменена.Длина

не может быть изменена непосредственно вне класса Base, так как он является закрытым членом класса Base, однако вы можете изменить его, используя функцию-член класса Base.

Что тогда делает функция increaseLengthByOne?

Производный класс может получить доступ к открытым / защищенным элементам Базового класса как таковым, когда вы вызываете increaseLengthByOne в производном классе, он выполняет Base функцию класса increaseLengthByOne, которая увеличивает длину.

как бы мне сделать так, чтобы функция increaseLength могла увеличиваться dLength?

Есть 2 способа сделать это
1) Просто добавьте dLength++ к вашей функции newFunction() т.е.

void Derived::newFunction()
{
    std::cout << "New function working";
    dLength++;
    increaseLengthByOne();
}

2) Если вы хотите сохранить имя функции increaseLengthByOne таким же, вы можете переопределить его в производном классе, т.е.

class Derived : public Base 
{
   private:
    int dLength;
   public: 
    void newFunction();
    void increaseLengthByOne();  //this overrides Base class function
};

void Derived::increaseLengthByOne()
{
    dLength++;
    Base::increaseLengthByOne();   //this increases length;
}
0 голосов
/ 11 февраля 2019

Закрытый член не будет доступен вне класса. Но вы всегда можете написать функцию-обертку или вспомогательную функцию, чтобы предоставить ей доступ за пределами мира. Это происходит в вашем случае. Так что значение длины будет увеличиваться.

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

Насколько я понимаю, [...] длина не может быть изменена.

Вы неправильно поняли.Член, являющийся частным, не означает, что его нельзя изменить.

Что тогда делает функция incrementLengthByOne?

Увеличивает член length.

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

Как производный класс использует эту функцию?

Когда функция Base является открытой или защищенной, функция производного класса может просто вызывать функцию Base.

Когда функция Base является закрытой, функция производного класса не может напрямую вызывать ее.

Ниже я слегка коснулся вашего кода для инициализации и продемонстрировал вызов функции производного класса для базовых функций.

Примечания:

  • Не забудьте инициализировать ваши атрибуты данных - я предпочитаю список инициализации ctor.

  • используйте cout дляпоказать, что происходит, их легко удалить для отправки

  • научиться использовать gdb


#include <iostream>
using std::cout, std::endl;  // feature requires -std=c++17


class Base
{
private:
   int length;

public:
   Base(int lInit = 0) : length(lInit)  // init length
      { cout << "\n  length init: " << length << endl; }

   void increaseLengthByOne();
};

void Base::increaseLengthByOne()
{
   length++;   // this->length++;
   cout <<  "\n  length++ : " << length;
}

class Derived : public Base
{
private:
   int dLength;

public:
   Derived() : Base(1), dLength(0)  // init Base and dLength
      { cout << "\n  dLength init: " << dLength << endl; }

   void newFunction(int d);
};

void Derived::newFunction(int d)
{
   cout << "\n  Derived::newFunction(int)";
   cout << "\n  dLength a: " << dLength;
   dLength = d;
   cout << "\n  dLength b: " << dLength;
   increaseLengthByOne();
   cout << "\n  dLength c: " << dLength;
}


class T989_t
{
public:
   int operator()() { return exec(); } // functor entry

private: // methods
   int exec()
      {
         Derived d;
         d.newFunction(5);    
         return 0;
      }
}; // class T98_t

int main(int , char** ) { return T989_t()(); } // invoke functor

Вывод:

  length init: 1

  dLength init: 0

  Derived::newFunction(int)
  dLength a: 0
  dLength b: 5
  length++ : 2
  dLength c: 5
0 голосов
/ 11 февраля 2019

Это не потому, что не видно, что он не существует или не может получить к нему доступ.Метод сможет получить доступ к переменной-члену, поскольку он был объявлен как имеющий доступ к ней.

Это принцип видимости и для вызовов традиционных методов, такой метод может обращаться к частному или защищенному членукласс, даже если код вызывающего абонента не может.

...