Что такое спецификаторы доступа? Должен ли я наследовать с частным, защищенным или публичным?
Я смущен значением модификаторов доступа в отношении наследования. В чем разница между наследованием, включающим private
, protected
и public
ключевые слова?
2 ответов
что такое спецификаторы доступа?
есть 3 access specifiers
для класса / структуры / объединения в C++. Эти спецификаторы доступа определяют способ доступа к членам класса. Конечно, любой член класса доступен внутри этого класса (внутри любой функции-члена этого же класса). Переходя к типу спецификаторов доступа, они:
общественные - члены, объявленные как Public, доступны извне класса через объект класс.
защищенный - члены, объявленные защищенными, доступны извне класса но только в классе, производном от него.
частная - эти члены доступны только изнутри класса. Внешний доступ запрещен.
Пример Исходного Кода:
class MyClass
{
public:
int a;
protected:
int b;
private:
int c;
};
int main()
{
MyClass obj;
obj.a = 10; //Allowed
obj.b = 20; //Not Allowed, gives compiler error
obj.c = 30; //Not Allowed, gives compiler error
}
спецификаторы наследования и доступа
наследование в C++ может быть одним из следующие типы:
-
Private
наследование -
Public
наследование -
Protected
наследование
вот правила доступа членов относительно каждого из них:
первое и самое главное правило
Private
члены класса никогда не доступны из любого места, кроме членов одного и того же класс.
Открытое Наследование:
все
Public
члены базового класса становятсяPublic
члены производного класса &
Все!--8--> члены базового класса становятсяProtected
члены производного класса.
т. е. никаких изменений в доступе членов. Правила доступа, которые мы обсуждали ранее, далее применяются к этим членам.
Пример Кода :
Class Base
{
public:
int a;
protected:
int b;
private:
int c;
};
class Derived:public Base
{
void doSomething()
{
a = 10; //Allowed
b = 20; //Allowed
c = 30; //Not Allowed, Compiler Error
}
};
int main()
{
Derived obj;
obj.a = 10; //Allowed
obj.b = 20; //Not Allowed, Compiler Error
obj.c = 30; //Not Allowed, Compiler Error
}
Закрытое Наследование:
все
Public
члены базового класса становятсяPrivate
члены производного класса &
Все!--8--> члены базового класса становятсяPrivate
члены производного класса.
пример кода:
Class Base
{
public:
int a;
protected:
int b;
private:
int c;
};
class Derived:private Base //Not mentioning private is OK because for classes it defaults to private
{
void doSomething()
{
a = 10; //Allowed
b = 20; //Allowed
c = 30; //Not Allowed, Compiler Error
}
};
class Derived2:public Derived
{
void doSomethingMore()
{
a = 10; //Not Allowed, Compiler Error, a is private member of Derived now
b = 20; //Not Allowed, Compiler Error, b is private member of Derived now
c = 30; //Not Allowed, Compiler Error
}
};
int main()
{
Derived obj;
obj.a = 10; //Not Allowed, Compiler Error
obj.b = 20; //Not Allowed, Compiler Error
obj.c = 30; //Not Allowed, Compiler Error
}
Защищенное Наследование:
все
Public
члены базового класса становятсяProtected
члены производного класса &
ВсеProtected
члены базового класса становятсяProtected
члены производного класса.
Пример Кода:
Class Base
{
public:
int a;
protected:
int b;
private:
int c;
};
class Derived:protected Base
{
void doSomething()
{
a = 10; //Allowed
b = 20; //Allowed
c = 30; //Not Allowed, Compiler Error
}
};
class Derived2:public Derived
{
void doSomethingMore()
{
a = 10; //Allowed, a is protected member inside Derived & Derived2 is public derivation from Derived, a is now protected member of Derived2
b = 20; //Allowed, b is protected member inside Derived & Derived2 is public derivation from Derived, b is now protected member of Derived2
c = 30; //Not Allowed, Compiler Error
}
};
int main()
{
Derived obj;
obj.a = 10; //Not Allowed, Compiler Error
obj.b = 20; //Not Allowed, Compiler Error
obj.c = 30; //Not Allowed, Compiler Error
}
помните, такие же правила доступа применяются к классам и членам вниз по иерархии наследования.
важно заметить:
- спецификация доступа для каждого класса не для каждого объекта
обратите внимание, что спецификация доступа C++ работает на основе каждого класса и не для каждого объекта.
Хорошим примером этого является то, что в конструкторе копирования или функции оператора присваивания копирования можно получить доступ ко всем элементам передаваемого объекта.
- производный класс может получить доступ только к членам своего базового класса
рассмотрим следующий пример кода:
class Myclass
{
protected:
int x;
};
class derived : public Myclass
{
public:
void f( Myclass& obj )
{
obj.x = 5;
}
};
int main()
{
return 0;
}
это дает ошибку компиляции:
prog.cpp:4: error:’ int Myclass::x ' защищен
потому что производный класс может получить доступ только к членам своего собственный базовый класс. Обратите внимание, что объект obj
быть переданным здесь никоим образом не связано с derived
функция класса, в которой он доступен, это совершенно другой объект и, следовательно,derived
функция-член не может получить доступ к своим членам.
что это friend
? Как это friend
повлиять на правила разграничения доступа?
вы можете объявить функцию или класс friend
другого класса. При этом правила спецификации доступа не применяются к friend
класс/функция ed. Класс или функция может получить доступ ко всем членам определенного класса.
так что
friend
перерыв инкапсуляции ы?
нет, наоборот они усиливают Инкапсуляция!
friend
корабль используется для обозначения намеренное сильное сцепление между двумя сущностями.
Если существует особая связь между двумя сущностями, такая, что один нуждается в доступе к другим private
или protected
участники, но вы не хотите все доступ с помощью public
спецификатор доступа, то вы должны использовать friend
корабль.
объяснение Скотта Мейерса в эффективном C++ может помочь понять, когда их использовать-публичное наследование должно моделировать отношения, тогда как частное наследование должно использоваться для "реализовано в терминах"-поэтому вам не нужно придерживаться интерфейса суперкласса, вы просто повторно используете реализацию.