доступ к закрытым членам в наследовании

У меня есть класс A, в котором поле val объявлено как закрытое. Я хочу объявить класс B, который наследуется от A и имеет доступ к val. Есть ли способ сделать это на С++?

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

Спасибо.


person ofer    schedule 23.11.2011    source источник
comment
Вы не можете получить доступ к приватному полю другого класса, неважно, является ли он предком. Если у вас нет общедоступных методов получения/установки, вам не повезло.   -  person Viruzzo    schedule 23.11.2011
comment
Этот вопрос был бы лучше, если бы вы разместили полный, минимальный пример программы, которую мы можем скомпилировать и протестировать, которая иллюстрирует то, что вы пытаетесь сделать.   -  person John Dibling    schedule 23.11.2011
comment
Вы можете затенить функцию данных/члена в A данными в B. Он вообще не изменит данные в B. Это не то же самое, что перегрузка, но в некоторых случаях это может сработать.   -  person Owl    schedule 15.07.2016


Ответы (6)


Быстрый ответ: вы этого не сделаете. Вот для чего предназначено ключевое слово protected, которое вы хотите использовать, если хотите предоставить доступ к подклассам, но никому другому.

private означает, что ни у кого нет доступа к этим переменным, даже у подклассов.

Если вы вообще не можете изменить код в A, возможно, для этой переменной существует метод доступа public/protected. В противном случае эти переменные не предназначены для доступа из подклассов, и помочь могут только хаки (которые я не поощряю!).

person Constantinius    schedule 23.11.2011
comment
Что вы думаете о приватном чисто виртуальном методе в родительском классе? почему компилятор показывает ошибку, чтобы переопределить ее? это значит, что они наследуют? - person Asif Mushtaq; 21.04.2016
comment
@UnKnown: да, чистые виртуальные функции необходимо переопределить, чтобы использовать базовый класс. - person Constantinius; 21.04.2016
comment
Это означает, что частные члены наследуют? потому что после объявления чистого виртуального метода как частной ошибки компилятора я переопределяю. - person Asif Mushtaq; 22.04.2016
comment
Наличие чистой виртуальной приватной функции противоречит ее цели: установить интерфейс, который должны реализовать наследующие классы. - person Constantinius; 22.04.2016
comment
@Constantinius Это неправда; например взгляните на isocpp.org/wiki/faq/strange-inheritance#private- виртуальные - person wonko realtime; 16.10.2020

Доступ к закрытым членам базового класса возможен только с помощью базовых функций-членов (а не производных классов). Так что у вас нет никаких прав, даже возможности сделать это :)

class Base

  • общедоступный: доступен всем.
  • private: доступ к ним возможен только из базовых функций-членов (не производных классов).
  • защищено: к нему могут обращаться как базовые функции-члены, так и производные классы.
person Schehaider Aymen    schedule 23.11.2011

Что ж, если у вас есть доступ к базовому классу, вы можете объявить класс B как дружественный класс. Но как объяснили другие: раз можно, это не значит, что это хорошая идея. Используйте защищенные члены, если вы хотите, чтобы производные классы могли получить к ним доступ.

person dbrank0    schedule 23.11.2011
comment
Я действительно удивлен, что это не имеет более высокого рейтинга, потому что оно делает две вещи: 1) дает правильный ответ (большинство ответов здесь в основном говорят, что это невозможно, вероятно, из-за того, что классы friend не так широко используются, поэтому они просто не не знаю об этой функции и/или потому что они исходят из языка, в котором нет чего-то подобного) и 2) упоминает, что это не очень хорошая идея. Лучшим ответом было бы сказать, ПОЧЕМУ это не очень хорошая идея, конечно. :) - person rbaleksandar; 19.11.2016

Это выполнимо, как описано в этом Гуру недели - GotW #76 – Использование и злоупотребление правами доступа. Но это следует рассматривать как крайнюю меру.

person Eoin    schedule 23.11.2011
comment
Я уже знал трюк #define, но эта страница изумительна! Спасибо! - person Ch3shire; 29.12.2016

Вам нужно определить его как protected. Защищенные члены наследуются дочерними классами, но недоступны из внешнего мира.

person B Faley    schedule 23.11.2011
comment
после наследования защищенных членов вы можете предоставить публичный доступ. тогда нам следует избегать хранения личных данных в спецификаторе защищенного доступа. - person Asif Mushtaq; 19.08.2015

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

#include<iostream>
using namespace std;

class A{
    int a;
    
    public:
    A(){};
    A(int val){a=val;};
    
    int get_a(){//To access a private variable it must be initialized here
        a=10;
        return a;
    }
};

class B: public A{
    int b;
    
    public:
    B(){};
    B(int val){b=val;};
    
    void get(){
        cout<<get_a();
    }
};

int main(){
    A ob1(2);
    cout<<ob1.get_a()<<endl;
    
    B ob2(4);
    ob2.get();
    
    return 0;
}
person Aayush peace    schedule 16.10.2020