Каждый элемент класса имеет уровень доступа — один из public (открытый), private (закрытый), protected (защищенный).
Этот уровень задается метками “public:”, “private:” и “protected:” в теле описания класса.
По умолчанию (при отсутствии метки) элементы имеют уровень доступа “private”.
Пример 1: Описание класса с различными уровнями доступа к объектам класса:
class A {
friend void func1(int);
int priv; // Закрытый член класса, так как описан в начале класса до задания уровня доступа
void priv_func(int); // Закрытый член класса, так как описан в начале класса до задания уровня доступа
public:
friend void func2(int);
int publ; // Открытый член класса, так как описан после задания уровня доступа “public”
void publ_func(int); // Открытый метод класса, так как описан после задания уровня доступа “public”
protected:
friend void func3(int);
int prot; // Защищенный член класса, так как описан после задания уровня доступа “protected”
int prot_func(int); // Защищенный метод класса, так как описан после задания уровня доступа “protected”
private:
int priv1; // Закрытый член класса, так как описан после задания уровня доступа “private”
int priv2; // Закрытый член класса, так как описан после задания уровня доступа “private”
public:
int publ1; // Открытый член класса, так как описан после задания уровня доступа “public”
};
-------------------------------------------------------------------
Уровень доступа регулирует использование элементов класса в постороннем коде: в коде дружественной функции разрешается обращение к любым элементам класса, в остальном коде вне методов данного класса разрешается обращение только к public элементам (за исключением protected элементов, см. пункт «Наследование»).
Пример 2. Правильное и ошибочное обращения к членам класса из постороннего кода (не из методов класса) (class A см.Пример 1):
void func() {
A a;
x1 = a.priv; // Ошибка: обращение к закрытому члену класса
a.priv_func(a.publ); // Ошибка: обращение к закрытому методу класса
a.publ_func(a.priv); // Ошибка: обращение к закрытому члену класса
x2 = a.publ;
a.publ_func(a.publ1);
x3 = a.prot; // Ошибка: обращение к защищенному члену класса
с4 = a.prot_func(a.priv); // Ошибка: обращение к защищенному методу класса и к закрытому члену класса
x4 = a.priv1; // Ошибка: обращение к закрытому члену класса
x5 = a.priv2; // Ошибка: обращение к закрытому члену класса
x6 = a.publ1;
x7 =
}
-------------------------------------------------------------------
Пример 3. Обращение к объектам класса из дружественной функции func2(): разрешены обращения к любым объектам класса (class A см.Пример 1)
void func2(int x) {
A a;
x1 = a.priv;
a.priv_func(a.publ);
a.publ_func(a.priv);
}
-------------------------------------------------------------------
class <имя производного класса> : <уровень доступа> <имя базового класса> {
// тело класса
};
Уровень доступа — это public (открытый), private (закрытый) или protected (защищенный), по умолчанию private.
public => все открытые и защищенные члены базового класса становятся открытыми и защищенными членами производного класса
private => все открытые и защищенные члены базового класса становятся закрытыми членами производного класса
protected => все открытые и защищенные члены базового класса становятся защищенными членами производного класса
Пример 4. Выведение класса (найдите ошибку в использовании private элемента и придумайте, как ее просто исправить):
class A {
int a;
public:
A(int aa):
a(aa)
{}
};
class B : A {
int b;
public:
B(int aa, int bb):
A(aa),
b(bb)
{ b = a * a; }
};
Как исправить:
1. Реализовать доступ к «a” (ввести функцию, возвращающую значение «a”)
2. Использовать «public” для определения доступа B к базовому классу
-------------------------------------------------------------------
Пример 5. Уровень доступа public:
#include <iostream>
using namespace std;
class base {
int i, j;
public:
void set(int a, int b) { i = a; j = b; }
void show() { cout << i << “ “ << j << “\n”; }
};
class derived: public base {
int k;
public:
derived(int x) { k = x; }
void showk() { cout << k << “\n”; }
};
int main() {
derived ob(3);
ob.set(1, 2); // обращение к методу класса base, так как set() определена только для base
ob.show(); // обращение к методу класса base, так как show() определена только для base
ob.showk(); // обращение к члену класса derived
return 0;
}
-------------------------------------------------------------------
Пример 6. Уровень доступа private (найдите отличие от примера 5):
// Эта программа не будет скомпилирована
#include <iostream>
using namespace std;
class base {
int i, j;
public:
void set(int a, int b) { i = a; j = b; }
void show() { cout << i << “ “ << j << “\n”; }
};
// Открытые члены класса base являются закрытыми членами класса derived
class derived: private base {
int k;
public:
derived(int x) { k = x; }
void showk() { cout << k << “\n”; }
};
int main() {
derived ob(3);
ob.set(1, 2); // Ошибка: доступ к функции set() запрещен
ob.show(); // Ошибка: доступ к функции show() запрещен
return 0;
}
-------------------------------------------------------------------
Пример 7. Уровень доступа protected:
#include <iostream>
using namespace std;
class base {
protected:
int i, j;
public:
void set(int a, int b) { i = a; j = b; }
void show() { cout << i << “ “ << j << “\n”; }
};
class derived: public base {
int k;
public:
void setk() { k = i * j; } // класс derived имеет доступ к членам i и j из класса base
void showk() { cout << k << “\n”; }
};
int main() {
derived ob(3);
ob.set(1, 2); // метод set() доступен классу derived
ob.show(); // метод show() доступен классу derived
ob.setk();
ob.showk();
return 0;
}
Пример 8. Уровень доступа выведенного класса с уровнем доступа к базовому protected:
#include <iostream>
using namespace std;
class base {
int i, j;
protected:
int m;
public:
void set(int a, int b) { i = a; j = b; }
void show() { cout << i << “ “ << j << “\n”; }
};
class derived: protected base {
int k;
public:
void setk() { k = i * j; } // класс derived имеет доступ к членам i и j из класса base
void showk() { cout << k << “\n”; }
};
int main() {
derived ob(3);
ob.set(1, 2); // Ошибка: открытый метод set() недоступен для посторонних функций, так как уровень доступа выведенного класса - protected
ob.show(); // Ошибка: метод set() недоступен для посторонних функций, так как уровень доступа выведенного класса - protected
int tmp = ob.m; // Ошибка: защищенный член класса недоступен для посторонних функций, так как уровень доступа выведенного класса - protected
int tmp = ob.i; // Ошибка: закрытый член класса недоступен для посторонних функций, так как уровень доступа выведенного класса - protected
return 0;
}
-------------------------------------------------------------------
Доступ к объектам класса из методов выведенного класса при различных типах доступа наследования:
|
: public |
: protected |
: private |
public: |
+ |
+ |
+ |
protected: |
+ |
+ |
+ |
private: |
- |
- |
- |
Доступ к объектам класса из посторонних функций при различных типах доступа наследования:
|
: public |
: protected |
: private |
public: |
+ |
- |
- |
protected: |
- |
- |
- |
private: |
- |
- |
- |
Задача для самостоятельного решения. Выяснить, можно ли добавить в описание библиотечного класса friend <имя функции> (и пользоваться этим в своей функции).