Написание статьи о protected привело к написанию этой. Я понял для какого из случаев предназначены модификаторы доступа private, public и protected.
private — Модификатор доступа, обозначющий, что программист будет использовать элементы класса только внутри непосредственно основного своего класса.
public — Модификатор доступа, обозначающий, что программист будет использовать элементы класса либо в других частях программы, либо в других классах.
protected — Модификатор доступа, обозначающий, что программист будет использовать элементы класса либо внутри непосредственно своего основного класса, либо непосредственно в своём потомке-классе.
Сейчас я попробую описать то же самое используя художественный стиль (может кому-то пригодиться).
Класс-наследник имеет поля и функции-члены базового класса, но не имеет права обращаться к собственным (private) полям и функциям базового класса. Вот и выходит так, что у основного класса есть такая часть, которую от сердца ему не оторвать: все наследники о ней знают, но использовать её не могут, так как родитель отказался передавать ту часть по наследству. Такая часть — это private.
Да вот мучает совесть родителя, не может родитель оставить детей без наследства, решает передать некоторую часть того, что у него есть, всем своим потомкам. Передаётся эта тайна от родителя к потомку, но скрыта она от всех посторонних и доступна исключительно детям собственным класса. Такая часть — это protected.
А чтобы не вспоминали родителя словом плохим, родитель передаёт еще часть наследства своим потомкам, и эта часть наследства озвучивается публично. Коли о наследстве озвучивается публично, то та часть, о которой озвучивается, может попасть не в руки потомков и использовать её сможет любой шарлатан. Такая часть — public.
Так вот обстоят дела с наследованием.
Иногда задают вопрос: "Если мы наследуем класс, наследуются ли приватные поля (члены)?. Ответ — да. Это легко проверить.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//Приватные поля наследуются clang Листинг #1
#include <conio.h>
#include <iostream>
usingnamespacestd;
classA
{
inta,b,c;//По умолчанию private.
};
classB:publicA//Применили наследование и на основе класса A создали класс B
{
};
classC//Независимый класс
{
};
intmain()
{
cout<<sizeof(A)<<endl;//Вывели на экран размер объекта от класса A
cout<<sizeof(B)<<endl;//Вывели на экран размер объекта от класса B
cout<<sizeof(C)<<endl;//Вывели на экран размер объекта от класса C
cin.get();
}
Посмотрим в код. С одной стороны у нас один класс с приватными переменными и два класса: один однозначно пустой, а второй неопределённого состояния: ни то пустой, ни то с наследством. Несложно догадаться, что пустой у нас класс C, а вот класс B в неопределённом для многих из нас, новичков, состоянии. Чтобы проверить, были ли унаследованы поля, можно сравнить размеры классов. Если класс B не унаследовал ничего, то размер его будет равен размеру пустого класса, а если унаследовал, то размер его будет равен размеру класса A.
В зависимости от системы результаты на экран могут быть вывдены разные, но в любом случае получится, что A == B, а размер C скорее всего будет сильно меньше (в моём случае А==12, B==12, C==1). Это обозначает однозначно, что поля потомок к себе получил. Несмотря на то, что использовать мы их не можем, они в потомке оказались. Вот мы и проверили, что приватные поля наследуются, висят в памяти. А ещё можем сделать вывод, что кроме пожирания памяти и не делают ничего, и использовать их нельзя. Одним словом — Паразиты.
Приватные элементы наследуются. Хотя всё равно могут быть несогласные. Важно понимать, что под наследованием могут иметь в виду сам механизм наследования, а не получаемый от наследования эффект.
Конструкторы и деструкторы не наследуются.
Все перегруженные операции наследуются.
начиная С++11 конструкторы (с рядом исключений) можно наследовать явно, путем применения using-декларации.
С наследованием конструкторов и деструкторов не так всё просто проверить. Я могу только констатировать. Хотя может создаваться видимость наследования в случае с конструктором по умолчанию, конструкторы и деструкторы не наследуются. Остальное из последнего честно содрано из одного ответа: http://www.cyberforum.ru/cpp-beginners/thread1192139-page2.html#post9670069.
7 комментариев на «“C++ для начинающих. private, public, protected внутри класса”»
class B:public A //Применили наследование и на основе класса A создали класс B
{
};
class C //Независимый класс
{
};
void main()
{
A obj_A; //Экземпляр класса A
B obj_B; //Экземпляр класса B
C obj_C; //Экземпляр класса С
std::cout<<sizeof(obj_A)<<std::endl; //Вывели на экран размер объекта от класса A
std::cout<<sizeof(obj_B)<<std::endl; //Вывели на экран размер объекта от класса B
std::cout<<sizeof(obj_C)<<std::endl; //Вывели на экран размер объекта от класса C
getch();
return;
}
Вот так выглядит итоговая программа, которая компилится у меня в 2010 студии.
спасибо
спасибо
очень интересно
спасибо.все подробно описано.разобрался
топ
#include <iostream> вместо #include <iostream.h> — студия 2010 не поняла
«A obj_A; //Экземпляр класса A
B obj_B; //Экземпляр класса B
C obj_C; //Экземпляр класса С» перенести в main
либо в начало файла добавить using namespace std
либо использовать std::cout и std::endl
Иначе ничего не заработает
#include <conio.h>
#include <iostream>
class A
{
int a,b,c; //По умолчанию private.
};
class B:public A //Применили наследование и на основе класса A создали класс B
{
};
class C //Независимый класс
{
};
void main()
{
A obj_A; //Экземпляр класса A
B obj_B; //Экземпляр класса B
C obj_C; //Экземпляр класса С
std::cout<<sizeof(obj_A)<<std::endl; //Вывели на экран размер объекта от класса A
std::cout<<sizeof(obj_B)<<std::endl; //Вывели на экран размер объекта от класса B
std::cout<<sizeof(obj_C)<<std::endl; //Вывели на экран размер объекта от класса C
getch();
return;
}
Вот так выглядит итоговая программа, которая компилится у меня в 2010 студии.
Выводит:
12
12
1