|
Модификаторы. Модификаторы public. Модификаторы public, private и protected в С#
Модификаторы public, private и protected в С#
Модификаторы доступа Public, private и protected — это модификаторы доступа, а не видимости, как ошибочно думают некоторые. Ниже кратко написаноб, кому какой доступ они предоставляют.
Public — доступ открыт всем другим классам, кто видит определение данного класса. Protected — доступ открыт классам, производным от данного. То есть, производные классы получают свободный доступ к таким свойствам или метода. Все другие классы такого доступа не имеют. Private — доступ открыт самому классу (т.е. функциям-членам данного класса) и друзьям (friend) данного класса - как функциям, так и классам. Однако производные классы не получают доступа к этим данным совсем. И все другие классы такого доступа не имеют.
Далее приведены примеры доступа с указанием, какие поля в каких местах программы доступны.
class some {
friend void f(some&);
public:
int a_;
protected:
int b_;
private:
int c_;
};
void f(some& obj) {
obj.a_ = 0; // OK
obj.b_ = 0; // OK
obj.c_ = 0; // OK
}
void g(some& obj) {
obj.a_ = 0; // OK
obj.b_ = 0; // compile time error
obj.c_ = 0; // compile time error
}
class derived : public some {
derived() {
a_ = 0; // OK
b_ = 0; // OK
c_ = 0; // compile time error
}
};
Модификаторы наследования В C# существует public-наследование, private-наследование и protected-наследование. В зависимости от того, какой тип используется, изменяется доступ к членам базового класса для клиентов производного. В таблице сведена информация об этом изменении: Модификатор наследования
| Модификатор доступа
| public
| private
| protected
| public-наследование
| public
| private
| protected
| private-наследование
| private
| private
| private
| protected-наследование
| protected
| private
| protected
| Следует добавить, что производный класс может изменить модификатор доступа с protected на public, разместив using объявление в соответствующей секции класса:
class some {
public:
int a;
protected:
int b;
private:
int c;
};
class derived : public some {
public:
using some::b;
};
void f(derived& obj) {
obj.b = 0; // OK
} Напоследок приведу несколько приёмов, с помощью которых можно «достучаться» до закрытых функций или данных. Допустим, у нас есть класс some и нам нужно обнулить закрытую переменную c:
Модифицировать определение класса, добавив друга (функцию или класс)
class some {
friend class some_friend;
public:
int a;
protected:
int b;
private:
int c;
};
class some_friend {
public:
static void hack(some& obj) {
obj.c = 0;
}
};
Воспользоваться препроцессором:
#define private public
class some {
public:
int a;
protected:
int b;
private:
int c;
};
void hack(some& obj) {
obj.c = 0;
}
Создать класс с таким же расположением в памяти и воспользоваться reinterpret_cast для преобразования указателей:
class some {
public:
int a;
protected:
int b;
private:
int c;
};
class hack_some {
public:
int a;
int b;
int c;
};
void h(some& obj) {
reinterpret_cast(&obj)->c = 0;
}
Если у «взламываемого» класса есть шаблонная функция, можно её специализировать своим типом:
class some {
public:
int a;
template void func(void) {
a = b + c;
}
protected:
int b;
private:
int c;
};
class hack_template_param{};
template<>
void some::func(void) {
c = 0;
}
void hack(void) {
some o;
o.func();
}; Очевидно, что способ с reinterpret_cast работает только для доступа к закрытым членам данных или вызова виртуальных функций. Остальные же способы позволяют как модифицировать закрытые данные, так и вызывать закрытые невиртуальные методы.
PS: Для компиляторов GCC и CLANG существует опция -fno-access-control, которая позволяет отключить контроль доступа к членам класса со стороны компилятора.
| Так же в этом разделе:
Как сделать массив объектов, у которых конструктор имеет аргументы Борьба с ошибкой линковки "In function ... undefined reference to" при сборке с заранее скомпиленными библиотеками Создание объектов в цикле Про dynamic_cast в сравнении с Pascal Проверка кода, статический анализатор Про нужность виртуального деструктора Как срабатывают конструкторы, деструкторы и инициализация переменных в C++ Многомерные динамические массивы Как работать с указателями на объект Синтаксис объявления указателей на функции в С++ Указатель в языке C++, хорошее объяснение Как сделать FastCGI сервер на C/C++ Концепция объектно-ориентированной парадигмы предельно проста... Небольшой логгер стека вызовов для C++ Руководство новичка по эксплуатации компоновщика в C/C++ Как препроцессор узнает полный путь к заголовочному файлу библиотеки в GCC Лямбда-функции в C++ (стандарт С++11) Лямбда-выражения в C++0x (С++11) Что обозначает декларация const в описании метода C++: пример использования const-указателя C++: учебные материалы по контейнерным классам и алгоритмам Интервью с Бьерном Страуструпом о языке C++ C++: Ключевое слово explicit. Явные конструкторы Модификаторы public, private и protected в C++ Права доступа при наследовании в C++ Конструктор копирования в C++: объяснение и пример использования Константные методы и константные указатели в C++, краткие примеры Книга "Введение в язык Си++", третье издание Дружественные функции (методы) в С++ Дружественные классы в С++ Еще одна попытка объяснить, что такое ссылка и указатель, и чем они отличаются Что такое explicitly shared объекты и implicitly shared и чем они отличаются (краткое объяснение) Приведение типов в C++. Терминология, динамический полиморфизм Приведение типов в C++ Указатели, ссылки и массивы в C и C++: точки над i tutorial (подробное и простое объяснение) Как в C++ различать "константный указатель" и "указатель на константу" Подходы к разработке встраиваемого ПО на C++: Шаблоны Пример перебора std::unordered_map на C++ Пример передачи #define определений через флаги компилятора в GCC Что такое lvalue и rvalue в языке C++ Что такое l-value и r-value в С++. Простое и короткое объяснение Значения Lvalue и Rvalue Вопросы и ответы на RSDN. Что это такое lvalue и rvalue? Понимание преинкремента и постинкремента в языке C++ Приоритет операций в языке C++ Онлайн компиляторы C++ Как в C++ можно держать основные настройки программы и прочие конфигурирующие данные не в глобальной области видимости Порядок инициализации в конструкторах Как научиться понимать синтаксис языка C++ Возврат значений по ссылке, по адресу (указателю) и по значению в C++ Понимание наследования и механизма виртуальных методов в C++ Особенности модификатора Const в C++ при работе с указателями и ссылками Глава книги "C++. Практика многопоточного программирования" - Разработка конкурентного кода Как сделать константное свойство в классе в языке C++ Примеры работы с байтами через union и через memcpy
| |
|
|