Содержание
- 2. Статические переменные Статические данные относятся ко всем объектам класса. Такие данные используются, если - требуется контроль
- 3. Обращение к статическому элементу осуществляется с помощью оператора разрешения контекста и имени класса: ИмяКласса :: ИмяЭлемента
- 4. Статические члены-данные и члены-функции struct A{ int a; A(){a=10;} static int f(); }; int A::f(){return a;}
- 5. // делаем а - статическим struct A{ static int a; A(){a=10;} static int f(); }; int
- 6. // статический член- данных класса // нужно обязательно где-то в программе инициализировать: struct A{ static int
- 7. (по материалам cpp-reference.ru/patterns/creational-patterns/singleton/) Часто в системе могут существовать сущности только в единственном экземпляре, например, система ведения
- 8. Для решения этой проблемы паттерн Singleton возлагает контроль над созданием единственного объекта на сам класс. Доступ
- 9. Классическая реализация. class Singleton { // хидер "Singleton.h" private: static Singleton * p_instance; Singleton() ; Singleton(
- 10. Реализация С.Мейерса. // Singleton.h class Singleton { private: Singleton() ; Singleton( const Singleton&); Singleton& operator=( Singleton&
- 11. // Усовершенствованная реализация. class Singleton; // опережающее объявление class SingletonDestroyer { private: Singleton* p_instance; public: ~SingletonDestroyer();
- 12. // Singleton.cpp #include "Singleton.h" Singleton * Singleton::p_instance = 0; SingletonDestroyer Singleton::destroyer; SingletonDestroyer::~SingletonDestroyer() { delete p_instance; }
- 13. Достоинства паттерна Singleton: - Класс сам контролирует процесс создания единственного экземпляра. - Паттерн легко адаптировать для
- 14. Динамическая информация о типах Еще раз возвращаюсь к этому вопросу. Существует возможность узнавать информацию о классе
- 15. #include ( из книги Лафоре) #include using namespace std; class Base { virtual void vertFunc() {
- 16. int main() { Derv1* d1 = new Derv1; Derv2* d2 = new Derv2; if( isDerv1( d1)
- 17. #include #include using namespace std; class Base { virtual void vertFunc() { } }; class Derv1
- 18. template bool isType( Base* pUnknown) // проверочная функция - шаблонная { T* t_obj; if ( t_obj
- 19. if (isType (d1)) cout else cout if (isType (d2)) cout else cout if (isType (d1)) cout
- 20. Derv3* d3 = new Derv3; if (isType (d3)) cout else cout if (isType (d2)) cout else
- 21. Присваивание // Общий вид. class A { public: A(){ } // конструктор по умолчанию ~A() {
- 22. R-value и L-value ссылки Rvalue ссылка – это составной тип похожий на традиционную ссылку в C++.
- 23. Семантика перемещения Одной из наиболее значимых возможностей, введенных в С++ 11, была семантика перемещения. Можно использовать
- 24. #include #include #include // _setmode #include // _O_U16TEXT class X { }; void g(X&) { std::wcout
- 25. void f(X&& val) { g(std::move(val)); // val - неконстантное lvalue => // необходим std::move() для вызова
- 26. Если мы попытаемся объединить все три случая в обобщенном коде, то столкнемся с проблемой: template void
- 27. Т&& для параметра шаблона Т ведет себя иначе, чем Х&& для конкретного типа X. Однако синтаксически
- 28. (по материалу из https://habr.com/ru/post/242639/) Как известно, взятие ссылки на ссылку в С++ не допускается, но это
- 29. Так появилось правило сжатия ссылок. Это правило очень простое – одиночный амперсанд (&) всегда побеждает. Таким
- 30. Пример: func(4); // 4 это rvalue: T становится int double d = 3.14; func(d); // d
- 31. Функция move выполняет простую работу. Её задача: принять либо lvalue, либо rvalue параметр, и вернуть его
- 32. Из ru.stackoverflow.com/questions/490753/Конструктор-перемещения #include class Buffer { private: void destroy() { if (pBuff) delete[ ] pBuff; }
- 33. public: Buffer(const std::string& buff) : pBuff(nullptr) , buffSize( buff.length() ) { pBuff = new char[buffSize]; memcpy(pBuff,
- 34. Buffer& operator=(const Buffer& other) { destroy(); buffSize = other.buffSize; pBuff = new char[buffSize]; memcpy(pBuff, other.pBuff, buffSize);
- 35. Buffer(Buffer&& tmp) : pBuff( tmp.pBuff ) , buffSize( tmp.buffSize ) { tmp.pBuff = nullptr; } Buffer&
- 36. Buffer CreateBuffer( const std::string& buff) { Buffer retBuff(buff); return retBuff; } int main() { Buffer buffer1
- 37. class Intvec { private: void log(const char* msg) { cout } size_t m_size; int* m_data; public:
- 38. ~Intvec() { log("destructor"); if (m_data) { delete[ ] m_data; m_data = 0; } } Intvec(const Intvec&
- 39. void copy(){ Intvec v1(20); Intvec v2; cout v2 = v1; // присваивание копированием cout } int
- 40. Фрагмент вывода: assigning lvalue... [008FFAA4] copy assignment operator [008FF99C] copy constructor [008FF99C] destructor ended assigning lvalue...
- 41. // теперь создадим еще один вариант функции copy void copy2 (){ Intvec v1(20); Intvec v2; cout
- 42. Фрагмент вывода: assigning lvalue... [004FF914] constructor [004FF9E4] copy assignment operator [004FF8C4] copy constructor [004FF8C4] destructor [004FF914]
- 43. // тогда добавляем в класс оператор копирования перемещением Intvec& operator= (Intvec&& other) { log("move assignment operator");
- 44. Фрагмент вывода: assigning lvalue... [00F8F8A4] constructor [00F8F974] move assignment operator [00F8F8A4] destructor ended assigning lvalue... Лишние
- 45. Домашнее задание на неделю Проект 34. Создать базовый и производный класс полиморфной иерархии именем своей фамилии
- 47. Скачать презентацию