Унаследованная функция-член, обращающаяся к элементам данных

Рассмотрим пример кода ниже:

#include <iostream>

using namespace std;

class A
{
    private:
        static int a;
        int b;

    protected:

    public:

        A() : b(0) {}

        void modify()
        {
            a++;
            b++;
        }

        void display()
        {
            cout << a <<"\n";
            cout << b <<"\n";
        }

};

int A::a=0;

class B : public A {

    private:
        int b;

    public:
        B(): b(5)
        {
        }

};

int main()
{
    A ob1;
    B ob2;
    ob1.display();
    ob2.display();

    return 0;

}

В приведенном выше коде class A имеет частный элемент данных b, а class B также имеет закрытый элемент данных b. Функция display() используется для отображения элементов данных. Когда я вызываю display() с помощью ob1.display(), display() обращается к частному члену данных b класса A. Я это понимаю. Но когда я вызываю display с помощью ob2.display, к какому b обращается display()? Это b класса А или b класса Б? Пожалуйста, объясните, почему он обращается к class A's b или class B's b


person nitin_cherian    schedule 05.01.2012    source источник


Ответы (3)


Он получит доступ к A::b. Реализация метода display в классе A вообще не имеет понятия о существовании B::b, не говоря уже об его использовании. Во всех смыслах и целях B::b отделено от A::b. Только в рамках самого B конфликт имен заставляет b ссылаться на B::b, скрывая A::b. Переменные-члены не могут быть virtual.

person mmx    schedule 05.01.2012
comment
Спасибо. Итак, в чем польза от class B наследования функции class A's display(). class B унаследовал функцию display() от class A, поэтому я ожидал, что display() получит доступ к class B's b - person nitin_cherian; 05.01.2012
comment
@LinuxPenseur Есть много применений. Это просто не один из них. Чтобы достичь того, чего вы хотите, вы можете либо не вводить новую переменную, а инициализировать базовый класс b с помощью вызова базового конструктора, либо ввести метод virtual в базовом классе, который возвращает значение b в базовом классе и переопределить его, чтобы вернуть значение b в производном классе. - person mmx; 05.01.2012
comment
Или просто иметь метод в производном классе, который обращается к членам производного класса и распространяет вызов дальше, вызывая метод базового класса, который обращается к членам базового класса. - person Alok Save; 05.01.2012

ob2.display() получит доступ к члену производного класса.
Вызов функции-члена всегда оценивается для this, this->display() для this в случае, если он указывает на объект вашего базового класса, и, следовательно, любая ссылка на b внутри функции display() оценивается как this->b, что равно b Базового класса.

Это связано с тем, что display() базового класса ничего не знает о том, происходит ли от него какой-либо другой класс. Базовый класс всегда независим от производного класса. Чтобы решить проблему, следует обычный шаблон, который заключается в предоставлении метода display() в классе Derived, который затем, в свою очередь, вызывает метод dsiplay() базового класса.

void B::display()
{
    //cout << a <<"\n";
    cout << b <<"\n";
    A::display();    
}
person Alok Save    schedule 05.01.2012
comment
Обратите внимание, что функция отображения относится к классу А, если вы ее пропустили. Не могли бы вы перефразировать свой ответ на его основе. Я говорю это потому, что ob2.display, похоже, не имеет доступа к члену производного класса. - person nitin_cherian; 05.01.2012
comment
Теперь у меня есть сомнения :). почему указатель this в случае ob2.display() указывает на объект базового класса? ob2 является объектом производного класса. - person nitin_cherian; 05.01.2012
comment
@LinuxPenseur: поскольку display() является членом базового класса. Вызов display() разрешается в рамках базового класса A. Базовый класс ничего не знает о каких-либо других классах, которые могут быть производными от него, если вы думаете об этом, это имеет смысл что такой обратной зависимости нет. b в производном классе будет упоминаться только тогда, когда он находится в области действия производного класса. - person Alok Save; 05.01.2012

Это класс A. A::display() не может получить доступ к закрытым членам B.

person Mahesh    schedule 05.01.2012
comment
Ответил на эту часть вопроса. Но когда я вызываю дисплей с помощью ob2.display, какой b имеет доступ к display ()? - person Mahesh; 05.01.2012