2013-08-01 3 views
0

Предположим, что существует два класса Base и DerivedКаков размер класса, когда он унаследован от класса, у которого все его члены закрыты в C++?

class Base 
{ 
    private: 
int a; 
} 
class Derived:public Base 
{ 
private: 
int b; 
} 
int main() 
{ 
Derived d; 
cout<<sizeof(d); 
    } 

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

+1

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

+0

@jrok: На самом деле отношения is-a не относятся к частному наследованию. – abarnert

+0

@abarnert Фактически, если речь идет о макете * класса (это целая тема здесь), она * делает * удержание. Это не может быть иначе, иначе ад сломается. – syam

ответ

3

Если у вас были не частные методы в вашем базовом классе, они могли бы получить доступ и изменить частных членов, поэтому члены все еще существуют, поскольку любые подклассы могут вызывать неличные методы.

Частные средства частные, не включают.

Почему у частных лиц в классе нет методов?

4

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

Закрытый не означает «удалить его, если он не используется» - это просто означает, что вы не можете использовать его вне класса ». Как правило, в классе будет некоторая функциональность использовать a и b в реальном классе, но так как это минимизируется, пока не станет более полезным примером, у вас этого нет.

Когда класс наследует (частные) переменные-члены из другого класса, они являются частью нового класса. Если они являются частными, это просто означает, что производный класс не может НАПРАВИЛЬНО использовать их - опять же, в реальном классе, который не настолько сведен к минимуму, это будет функция, чтобы использовать a в классе Base, а некоторые функции в Derived - использование b.

2

Когда вы наследуете класс, ваш макет памяти класса - это все, что имеет базовый класс, за которым следует все, что вы определяете в новом классе.

Вы можете думать, что класс B, который наследуется от A, является A плюс новые дополнения класса B.

0

Если база не имеет методов манипулирования частными членами, то производные все еще не могут получить доступ к элементам, однако исключение является членом-членом базы. Сделайте приватный член защищенным, а не частным, если вы хотите получить доступ к производным. Удостоверьтесь, что производные остатки являются государственной наследующей базой. Имейте в виду, что производный класс унаследовал весь базовый класс: включая частных членов, однако, без каких-либо методов манипулирования в базе, частный член var бесполезен, если конструктор не делает что-то с ним, что не будет хорошей практикой.

0

Вопрос фактически не имеет ничего общего с наследованием. Существует класс с частными полями, без методов и без друзей. По сути, поля никогда не могут быть доступны. Почему он не обрабатывается одинаково с пустым классом всюду, включая наследование? Большинство компиляторов оптимизируют пустые базовые классы.

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

0

Фактический ответ здесь немного сложнее, чем кажется.

Derived не является стандартным классом макета, так как и самый производный класс, и как минимум один базовый класс имеют нестатические элементы.Поэтому макет полностью зависит от реализации. Вы не можете предсказать ничего о смещении его членов или размере класса. Он может быть эквивалентным структуре с b, непосредственно следуя a, или к структуре с только b в ней или к структуре с a после b после 69105 байт заполнения.

Итак, тот факт, что компилятору разрешено обнаруживать, что вы не можете получить доступ к Derived::a в своем коде, является красная селедка.

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

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