Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемНаталия Тимакина
2 Дружественные функции Дружественные функции – это функции, объявленные вне класса, но имеющие доступ к закрытым и защищенным полям данного класса Дружественная функция объявляется внутри класса с модификатором friend Дружественные функции не являются членами класса, поэтому им не передается указатель this Правило использования: Если нет важных доводов использовать дружественные функции – используйте вместо них члены класса Если важные доводы есть – подумайте, а действительно ли они так важны
3 Пример class Foo { void friend Bar(Foo & foo); private: int data; }; void Bar(Foo & foo) { foo.data = 1; }
4 Дружественные операции Дружественные операции, как и дружественные функции, могут иметь доступ к приватным и защищенным методам класса
5 Пример class CMyString { public: … CMyString const friend operator+(const char* left, CMyString const& right); private: }; CMyString const operator+(const char* left, CMyString const& right) { … }
6 Дружественные классы Некоторым классам может понадобиться доступ к закрытым данным друг друга Например, классу «дерево» может понадобиться доступ к закрытым полям его узлов В этом случае необходимо объявить дружественный класс внутри определения класса Дружественная связь между классами является самой сильной Реализации классов оказываются связанными, что противоречит принципу инкапсуляции Не используйте дружественные классы до тех пор, пока их использование не окажется единственным способом решения задачи
7 Пример class Bar; class Foo { friend class Bar; private: int data; }; class Bar { void Do(Foo & foo) { foo.data = 1; } };
9 Для чего нужны статические данные класса Класс – это тип данных Для каждого объекта создается своя собственная копия членов данных Методы класса работают с одним из экземпляров класса, на которые ссылается this Для некоторых классов естественными могли бы оказаться данные, общие для всех экземпляров данного класса Например, строковое представление имени класса Константы, общие для всех экземпляров класса, область видимости которых должна быть ограничена методами класса Такие поля и методы называют статическими и объявляют при помощи ключевого слова static
10 Особенности Статические методы не получают указатель this Статические методы могут обращаться только к статическим данным класса Статические методы могут вызывать только статические методы Либо нестатические, если им передается указатель или ссылка на объект класса Статические методы имеют доступ к закрытым и защищенным полям и методам класса, через экземпляры классов Доступ к статическим методам и данным класса осуществляется по имени класса (создавать экземпляр не требуется)
11 Пример Foo.h: class Foo { public: static std::string const GetClassName() { return m_className; } private: static std::string const m_className; }; Foo.cpp: #include Foo.h std::string const Foo::m_className = Foo;
12 Область применения Запрещение создания объектов в области стека Паттерн «одиночка» (singleton) Объект с глобальным доступом, существующий в программе в единственном экземпляре Методы и данные, характерные для класса в целом, а не для отдельных его экземпляров Создание классов-утилит
13 Пример – паттерн «Одиночка» // singleton.h class Singleton { public: static Singleton & GetInstance() { if (!m_pInstance) { m_pInstance = new Singleton(); } return *m_pInstance; } void SomeMethod(){} private: Singleton(){} static Singleton *m_pInstance; }; // singleton.cpp Singleton* Singleton::m_pInstance = NULL; int main(int argc, char * argv[]) { Singleton& singleton = Singleton::GetInstance(); singleton.SomeMethod(); return 0; }
15 Вложенное объявление классов и других типов данных Язык C++ позволяет разместить объявление одного класса (или другого типа данных) внутри объявления другого Это полезно, когда вложенный тип данных в основном используется лишь внешним классом, или совместно с ним Пример - итераторы стандартных контейнеров STL Использование вложенного класса Из методов внешнего класса – по имени вложенного класса Снаружи – при помощи указания имени внешнего класса: ExternalClass::Internal
16 Пример 1 class External { public: class Internal { public: void Foo(){} }; private: void Bar() { // из методов внешнего класса можем обращаться по имени Internal internal; internal.Foo(); } }; int main(int argc, char* argv[]) { External::Internal internal; internal.Foo(); return 0; }
17 Пример 2 – идиома «Pimpl» // ComplexClass.h class CComplexClass { public: CComplexClass(); void Foo(); ~CComplexClass(); private: // класс Impl хранит все // приватные данные и методы // класса CComplexClass class Impl; Impl * m_pImpl; }; // ComplexClass.cpp class CComplexClass::Impl { public: void Foo() { //… } private: //… }; CComplexClass::CComplexClass() :m_pImpl(new Impl()) { } CComplexClass::~CComplexClass() { delete m_pImpl; } void CComplexClass::Foo() { m_pImpl->Foo(); } Данный подход позволяет в языке C++ сократить количество зависимостей времени компиляции от модификации приватной части класса, т.к. она фактически вынесена из заголовочного файла в.CPP файл
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.