Member 11692369 Ответов: 1

Обеспечение более строгого доступа к производному классу В C++


Hi everyone i have one question is my mind

This program worked
-----------------------------------------
#include<iostream>
using namespace std;
//declaring base class
class Base {
public:
    virtual int fun(int i) { cout << "Base::fun(int i) called"; }
};
//Declaring Derived class
class Derived: public Base {
private:
    int fun(int x)   { cout << "Derived::fun(int x) called"; }
};
int main()
{
    Base *ptr = new Derived;
    ptr->fun(10);
    return 0;
}

//It worked and gave output as :
Derived::fun(int x) called

But the below program didn't worked, don't know why
-------------------------------------------------
#include<iostream>
using namespace std;
//Declaring base class
class Base {
private:
    virtual int fun(int i) { cout << "Base::fun(int i) called"; }
};
//Declaring Derived class
class Derived: public Base {
public:
    int fun(int x)   { cout << "Derived::fun(int x) called"; }
};
int main()
{
    Base *ptr = new Derived;
    ptr->fun(10);
    return 0;
}


Что я уже пробовал:

Я изучил виртуальные функции, но запутался в работе двух вышеперечисленных программ

1 Ответов

Рейтинг:
6

Jochen Arndt

Вторая версия будет генерировать ошибку компилятора. Компилятор видит доступ к Base::fun() что отрицается, потому что это личное.

В первой версии это разрешено, потому что Base::fun() является публичным. Поскольку функция является виртуальной, компилятор не будет генерировать код для прямого вызова кода функции, а будет использовать vtable объекта (динамическая отправка). Потому что объект имеет тип Derived, vtable будет указывать на Derived::fun() во время выполнения и это называется. Vtable не знает о доступности отправленной функции и поэтому работает даже тогда, когда эффективно вызываемая функция объявлена как частная.


CPallini

5.

Member 11692369

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

Member 11692369

Теперь я понял это после того, как выучил Vtable и Vptr,
Спасибо

Jochen Arndt

Прекрасно, что вы это понимаете, и спасибо вам за то, что приняли мое решение.

Это сложная тема. Но вы можете избежать таких проблем, если будете следовать этому правилу:
Не изменяйте режим доступности виртуальных функций в производных классах.
Если вы должны сделать это по очень особой причине, задокументируйте это в своем коде.