2010-01-06 2 views
8

Я знаю, что производный класс не может получить доступ к частным членам базового класса, так почему производный класс наследует частных членов базового класса? Есть ли какой-нибудь случай, когда это полезно?Почему производный класс наследует частных членов базового класса?

Спасибо!

+10

Какая книга, которую вы изучаете на C++, может сказать по этому вопросу? – 2010-01-06 21:35:30

ответ

20

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

Например, притворитесь частный материал:

int i; 

и класс имеет Geti() и SETI(). Значение i должно быть помещено где-то, даже если оно является частным,

+0

Сэр, я признаю это, редко я сталкивался с таким изящным и удивительным ответом. Спасибо вам, сэр за этот ответ, особенно за последнюю строку :)) –

0

Производный класс никак не «наследует» частных членов базового класса - он не может получить к ним доступ, поэтому он не «наследует» их.

Экземпляр производного класса содержит примеры частных членов базового класса по очевидным причинам.

Так что я даже не знаю, что вы подразумеваете под этим вопросом.

+2

«Производный класс не« наследует »частных членов базового класса« Да, он делает », если вы не пытаетесь разделить синтаксические волоски. –

+1

Я предполагал, что «наследовать» он имел в виду «иметь доступ» - это было наименее бессмысленной интерпретацией вопроса. –

2

Причина в том, что производные классы имеют отношение is-a к суперклассу.

Атрибут производного класса IS - это суперкластерный экземпляр ... только с большим количеством (или меньше из-за установки некоторых функций суперкласса).

+2

Очень смущает кого-то нового для ООП – Jaywalker

+0

@Jaywalker Я не понимаю, как это сбивает с толку. Базовый класс производного класса _is-a_ и его базовый компонент по-прежнему должны иметь доступ к _its_ 'private' в своих методах, независимо от того, разрешил ли он производным классам использовать их напрямую. –

10

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

4

Базовый класс все еще может использовать переменные частного члена &.

Если вы хотите, чтобы производные классы имели доступ к членам, но не скрывали эти элементы из внешнего мира, сделайте их protected:.

Вот пример для иллюстрации:

class Base 
{ 
public: 
    Base() : val(42.0f) {}; 
    float GetValue() const 
    { 
    return val_; 
    } 
private: 
    float val_; 
}; 

class Derived : public Base 
{ 
public: 
    float ComputedValue() const 
    { 
    return GetValue() * 2.0f; 
    } 
}; 
4

Не забывайте, что базовый класс может иметь методы, которые не private, и, таким образом, доступ к производным классом. Те методы protected или public базового класса все еще могут ссылаться на методы базового класса private. Это особенно полезно, если вы хотите, чтобы заблокировать основную функциональность в базовом классе, например, с помощью реализации шаблона в Template Method дизайн:

class base 
{ 
public: 

    virtual ~base() { /* ... */ } 

    virtual void base_func() { foo_private(); } 
    virtual void do_func() = 0; 

private: 

    void foo_private() 
    { 
    // pre-do_func() operations 

    do_func(); 

    // post-do_function operations 
    } 

}; 

class derived : public base 
{ 
public: 

    void derived_func() { base_func(); } 

    virtual void do_func() 
    { 
    // Derived class specific operations 
    } 
}; 
2

Как было указано другими ответами здесь, производный класс синтаксически не может получить доступ к частные члены базового класса; но он должен иметь копию того же в макете памяти. Подумайте о кастинге. используя кастинг «C», вы можете наложить полученную на частную базу. Тогда компилятору понадобится правильное смещение памяти, чтобы создать допустимый макет памяти для базового объекта.

Ex.

class Base { 
public: 
    void printA() { 
    a = 10; 
    std::cout << a << std::endl; 
    } 
private: 
    int a; 
}; 
class Derived : private Base{ 
    int b; 
}; 

Derived* d = new Derived; 
Base* b = (Base*)d; 
b->printA(); 
0

При создании объекта класса объекта конструктор базового класса также вызывается для создания базового объекта. если частным членам базового класса не выделена память, базовый объект будет неполным.

Таким образом, производный объект класса наследует частные элементы базы, поскольку они созданы во время создания объекта базового класса, но недоступны, поскольку они являются частными.

0

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

Частные члены базового класса не имеют прямого доступа, а производятся базовым классом по производному классу.

Смежные вопросы