Права доступа при наследовании
С правами доступа при наследовании довольно легко запутаться. Мало того, что для данных и функций класса в С++ есть целых три уровня доступа: private, protected и public, еще ведь можно и само наследование сделать private, protected и public. Самым загадочным их них является protected-наследование. Запутаться во всем этом зоопарке очень просто, поэтому я аккуратно расписала где какой уровень досупа получится при каком наследовании. Известно, что private можно опускать при описании классов, private ставится по умолчанию. Но я не стала этого делать, чтобы было нагляднее.
Я беру базовый класс, CBase и смотрю какие из его данных видны его наследнику, наследнику наследника, и какие видны извне.
class CBase
{
private:
int privateBase;
protected:
int protBase;
public:
int pubBase;
};
Ни один из наследников не сможет доступиться к private-данным CBase. Как у них сложатся отношения с остальными данными зависит от того, как они были отнаследованы.
private наследование
Те данные, что в CBase были protected и public, стали private в CDerived.
class CDerived : private CBase
{
//унаследованные данные класса
//недоступно:
// int privateBase;
//private:
// int protBase;
//private:
// int pubBase;
public:
void updateDerived()
{
//privateBase=0; //нельзя доступиться
//к private данным CBase
protBase=0;
pubBase=0;
}
};
class CDerived1 : public CDerived
{
public:
void updateDerived1()
{
//privateBase=1; //нельзя доступиться
//к private данным CBase
//protBase=1;//protBase недоступно,
//потому что CDerived использовал
//private при наследовании от CBase
//pubBase=1; //pubBase недоступно, потому что
//CDerived использовал private
//при наследовании от CBase
}
};
При вызове извне, доступиться не получится ни к чему
CDerived dd;
//dd.privateBase=3; недоступно
//dd.protBase=3; недоступно
//dd.pubBase=3; недоступно
protected наследование
Редкий зверь. Встречается в тестах и на собеседованих. Удачных способов его применения в реальной жизни мало.
Те даннные, что в CBase были protected и public стали protected.
class CDerived : protected CBase
{
//унаследованные данные класса
//недоступно:
// int privateBase;
//protected:
// int protBase;
//protected:
// int pubBase;
public:
void updateDerived()
{
//privateBase=0; //нельзя доступиться к
//private данным CBase
protBase=0;
pubBase=0;
}
};
class CDerived1 : public CDerived
{
public:
void updateDerived1()
{
//privateBase=1; //нельзя доступиться к
//private данным CBase
protBase=1; //а тут уже все в порядке,
//в CDerived они стали protected
pubBase=1; // что значит, что наследник имеет
//к ним доступ
}
};
Доступ извне:
CDerived dd;
//dd.privateBase=3; недоступно
//dd.protBase=3; недоступно
//dd.pubBase=3; недоступно
public наследование
protected и public данные из CBase остаются, соответственно protected и public.
class CDerived : public CBase
{
//унаследованные данные класса
//недоступно:
// int privateBase;
//protected:
// int protBase;
//public:
// int pubBase;
public:
void updateDerived()
{
//privateBase=0; //нельзя доступиться к
//private данным CBase
protBase=0;
pubBase=0;
}
};
class CDerived1 : public CDerived
{
public:
void updateDerived1()
{
//privateBase=1; //нельзя доступиться к
//private данным CBase
protBase=1;
pubBase=1;
}
};
Доступ извне:
CDerived dd;
//dd.privateBase=3;
//dd.protBase=3;
dd.pubBase=3; //pubBase остался с уровнем доступа public,
//к нему теперь можно доступиться.