SlideShare una empresa de Scribd logo
1 de 34
Descargar para leer sin conexión
Базовые	
  возможности	
  C++
ЛЕКЦИЯ	
  №3
7.	
  сохраняемость
Сохраняемость -­‐ способность	
  объекта	
  существовать	
  во	
  времени,	
  переживая	
  
породивший	
  его	
  процесс,	
  и	
  (или)	
  в	
  пространстве,	
  перемещаясь	
  из	
  своего	
  
первоначального	
  адресного	
  пространства.
Как	
  передать	
  объект	
  на	
  другую	
  
машину?
3
А	
  что	
  если	
  объект	
  сложный?
граф	
  объектов
Задача	
  сериализации объекта,	
  включающего	
  только	
  поля	
  из	
  элементарных	
  типов	
  значений	
  
и	
  строк,	
  не	
  представляет	
  принципиальных	
  трудностей.	
  Для	
  такого	
  объекта	
  в	
  ходе	
  
сериализации в	
  поток	
  записываются	
  сами	
  значения	
  всех	
  полей	
  объекта.	
  Однако	
  в	
  общем	
  
случае	
  объект	
  содержит	
  ссылки	
  на	
  другие	
  объекты,	
  которые,	
  в	
  свою	
  очередь,	
  могут	
  
ссылаться	
  друг	
  на	
  друга,	
  образуя	
  так	
  называемый	
  граф	
  объектов	
  (object graph).	
  
4
class SampleClass
{
SampleClass fieldA = nullptr;
SampleClass fieldB = nullptr;
}
...
SampleClass root = new SampleClass();
SampleClass child1 = new SampleClass();
SampleClass child2 = new SampleClass();
root.fieldA = child1;
root.fieldB = child2;
child1.fieldA = child2;
Просто	
  пронумеруем	
  объекты
почти	
  как	
  ссылки	
  в	
  C++
1. ObjectID ?
В	
  ходе	
  сериализации объектам	
  должны	
  быть	
  поставлены	
  в	
  соответствие	
  некоторые	
  
идентификаторы,	
  и	
  в	
  хранилище	
  отдельно	
  сохраняется	
  список	
  объектов,	
  отмеченный	
  
идентификаторами,	
  а	
  при	
  сериализации вместо	
  ссылок	
  записываются	
  идентификаторы	
  
ссылаемых	
  объектов.
2. Виртуальный	
  адрес!
В	
  программе	
  роль	
  идентификатора	
  объекта	
  выполняет	
  его	
  адрес,	
  но	
  вместо	
  него	
  обычно	
  
удобнее	
  назначить	
  некоторые	
  идентификаторы	
  в	
  процедуре	
  сериализации для	
  более	
  
легкого	
  чтения	
  человеком	
  полученного	
  образа.
3. Hash-­‐map	
  …
В	
  ходе	
  сериализации нужно	
  ввести	
  список	
  адресов	
  уже	
  записанных	
  объектов,	
  как	
  для	
  
ведения	
  списка	
  идентификаторов,	
  так	
  и	
  для	
  обнаружения	
  возможных	
  циклов	
  при	
  
обходе	
  графа	
  методом	
  в	
  глубину.
5
Пример
Example14_Serialize
1. class A {
2. public:
3. A(const char* value) : next(nullptr), name(value) {};
4. A(std::ifstream &is) {
5. bool is_next;
6. is >> name;
7. is >> is_next;
8. if (is_next) next = new A(is);}
9. void Serialize(std::ofstream &os) {
10. os << name << std::endl;
11. if (next != nullptr) {
12. os << true;
13. next->Serialize(os);} else os << false;}
14. void SetNext(A* value) {
15. next = value; }
16. virtual ~A() { delete next; }
17.private:
18. std::string name;
19. A* next;
20.};
Полезные	
  приемы	
  по	
  работе	
  с	
  классами
Временные	
  объекты
Вре́менные объекты — в	
  C++	
  объекты,	
  
которые	
  компилятор	
  создаёт	
  автоматически	
  
по	
  ходу	
  вычисления	
  выражений.	
  Такие	
  
объекты	
  не	
  имеют	
  имени	
  и	
  уничтожаются	
  
сразу	
  же,	
  как	
  только	
  в	
  них	
  исчезает	
  
потребность.
Пример:
string r = string("1") + "2" + "3";
string r, tmp1, tmp2, tmp3;
tmp1.ctor("1");
tmp2.ctor();
tmp2 = tmp1 + "2";
tmp3.ctor();
tmp3 = tmp2 + "3";
r.ctor(tmp3);
tmp3.dtor();
tmp2.dtor();
tmp1.dtor();
Модификаторы	
  функций
Example15_Virtual
Ключевое	
  слово virtual опционально	
  и	
  поэтому	
  немного	
  затрудняло	
  чтение	
  кода,	
  заставляя	
  
вечно	
  возвращаться	
  в	
  вершину	
  иерархии	
  наследования,	
  чтобы	
  посмотреть	
  объявлен	
  ли	
  
виртуальным	
  тот	
  или	
  иной	
  метод.
Типовые	
  ошибки: Изменение	
  сигнатуры	
  метода	
  в	
  наследнике.
Модификатор	
  override позволяет	
  указать	
  компилятору,	
  что	
  мы	
  хотим	
  переопределить	
  
виртуальный	
  метод.	
  Если	
  мы	
  ошиблись	
  в	
  описании	
  сигнатуры	
  метода	
  – то	
  компилятор	
  
выдаст	
  нам	
  ошибку.	
  Этот	
  модификатор	
  влияет	
  только	
  на	
  проверки	
  в	
  момент	
  компиляции.
Модификатор	
  final
Example28_Final
Модификатор	
  final,	
  указывающий	
  что	
  производный	
  класс	
  не	
  должен	
  переопределять	
  
виртуальный	
  метод.
Работает	
  только	
  с	
  модификатором	
  virtual.	
  Т.е.	
  Создавать	
  «копию»	
  функции	
  в	
  классе-­‐
наследнике	
  с	
  помощью	
  этой	
  техники	
  запретить	
  нельзя.
Применяется,	
  в	
  случае	
  если	
  нужно	
  запретить	
  дальнейшее	
  переопределение	
  метода	
  в	
  
дальнейших	
  наследниках	
  наследника	
  (очевидно,	
  что	
  в	
  родительском	
  классе	
  такой	
  
модификатор	
  ставить	
  бессмысленно).
Модификатор	
  const
Example29_Const
сonst,	
  применительно	
  к	
  методу	
  (например,	
  void	
  foo	
  const {})	
  означает,	
  что	
  метод	
  не	
  может	
  
вызывать	
  другие	
  методы	
  без	
  модификатора	
  const и	
  не	
  может	
  менять	
  значения	
  атрибутов	
  
объекта.
class A{
int a;
void fooA2() {}
void fooA () const{
fooA2(); //ошибка
a=7; // ошибка
}
mutable
Example33_Mutable
Ключевое	
  слово	
  mutable позволяет	
  специфицировать	
  
атрибуты	
  класса,	
  которые	
  могут	
  меняться	
  из	
  const
методов.
Иногда	
  необходимо	
  иметь	
  такие	
  атрибуты	
  для	
  
«служебных	
  целей»,	
  например,	
  подсчитывать	
  число	
  
обращений	
  к	
  методу	
  и	
  т.д.
Const
Example23_Const
1. int a=100;//два обычных объекта типа int
2. int b=222;
3. int *const P2=&a; //Константный указатель
4. *P2=987; //Менять значение разрешено
5. //P2=&b; //Но изменять адрес не разрешается
6. const int *P1=&a; //Указатель на константу
7. //*P1=110; //Менять значение нельзя
8. P1=&b; //Но менять адрес разрешено
9. const int *const P3=&a;//Константный указатель на константу
10.//*P3=155; //Изменять нельзя ни значение
11.//P3=&b; //Ни адрес к которому такой указатель привязан
Constexpr
Example31_constexpr
Позволяет	
  создавать	
  выражения,	
  вычисляемые	
  на	
  этапе	
  компиляции	
  (позволяет	
  упростить	
  код).	
  
Ключевое	
  слово	
  constexpr,	
  добавленное	
  в	
  C++11,	
  перед	
  функцией	
  означает,	
  что	
  если	
  значения	
  
параметров	
  возможно	
  посчитать	
  на	
  этапе	
  компиляции,	
  то	
  возвращаемое	
  значение	
  также	
  
должно	
  посчитаться	
  на	
  этапе	
  компиляции.	
  Если	
  значение	
  хотя	
  бы	
  одного	
  параметра	
  будет	
  
неизвестно	
  на	
  этапе	
  компиляции,	
  то	
  функция	
  будет	
  запущена	
  в	
  runtime (а	
  не	
  будет	
  выведена	
  
ошибка	
  компиляции).
constexpr int sum (int a, int b){
return a + b;
}
void func(){
constexpr int c = sum (5, 12); // значение переменной будет посчитано на этапе
компиляции
}
Inheritance	
  /	
  наследование
Example24_MultipleInheritance
class temporary { /* ... */ };
class secretary : public
employee { /* ... */ };
class tsec
: public temporary, public
secretary { /* ... */ };
class consultant
: public temporary, public
manager { /* ... */ };
В	
  С++	
  в	
  отличии	
  от	
  большинства	
  других	
  
объектно-­‐ориентированных	
  языков	
  есть	
  
множественное	
  наследование!
Очень	
  плохо,	
  если	
  у	
  двух	
  родителей	
  класса	
  
есть	
  общий	
  родитель!
Ссылка	
  на	
  себя
Считается,	
  что	
  в	
  каждой	
  функции-­‐члене	
  
класса	
  X	
  указатель	
  this описан	
  неявно	
  как
X *const this;
class X {
int m;
public:
int readm() { return this->m; }
};
Ссылка	
  на	
  родителя
Example25_ReferenceToParent
class Parent {
public:
Parent(void);
~Parent(void);
void Foo(void);
};
class Child : public Parent {
public:
Child(void);
~Child(void);
void Foo(void);
};
void Parent::Foo(void)
{
std::cout << "Parentn";
}
void Child::Foo(void)
{
Parent::Foo();
std::cout << "Childn";
}
Виртуальные	
  деструкторы
Example26_VirtualDestructor
C++	
  вызывает	
  деструктор	
  для	
  текущего	
  типа	
  и	
  для	
  всех	
  его	
  родителей.
Однако,	
  если	
  мы	
  работаем	
  с	
  указателями	
  то	
  можем	
  попасть	
  в	
  неприятную	
  ситуацию,	
  когда	
  
вызываем	
  оператор	
  delete	
  у	
  указателя,	
  предварительно	
  приведя	
  его	
  к	
  типу	
  родителя.	
  В	
  
этом	
  случае,	
  вообще	
  говоря,	
  у	
  наследников	
  деструктор	
  вызван	
  не	
  будет (например,	
  если	
  у	
  
родителя	
  нет	
  деструктора).
Однако	
  если	
  объявить	
  деструктор	
  базового	
  класса	
  как	
  virtual	
  то	
  будут	
  вызваны	
  деструкторы	
  
всех	
  классов.
Всегда	
  объявляй	
  деструктор	
  как	
  virtual!
Последовательность	
  вызова	
  конструкторов	
  
и	
  деструкторов
Конструкторы	
  вызываются	
  начиная	
  от	
  родителя	
  к	
  наследнику.
Деструкторы	
  вызываются	
  начиная	
  от	
  наследника	
  к	
  родителю.
class A {}
class B : A {}
class C: B{}
Конструкторы:
A, B, C
Деструкторы:
~C, ~B,~A
Явные	
  и	
  неявные	
  конструкторы
Example20_explicit	
  
В	
  С++	
  существуют	
  явные	
  и	
  неявные	
  конструкторы;	
  преобразования,	
  определенные	
  с	
  помощью	
  конструктора	
  со	
  
спецификатором	
  explicit могут	
  использоваться	
  только	
  при	
  явном	
  преобразовании,	
  в	
  то	
  время,	
  как	
  другие	
  
конструкторы	
  могут	
  использоваться	
  также	
  и	
  в	
  неявных	
  преобразованиях.	
  
Например:
// "обычный конструктор" определяет неявное преобразование
class A { S(int); };
A a1(1); // ok
A a2 = 1; // ok
void Foo(A);
Foo(1); // ok (но это может привести к неприятным
class E { explicit E(int); }; // явный конструктор
E e1(1); // ok
E e2 = 1; // ошибка (хотя это обычно является сюрпризом)
void f(E);
f(1); // ошибка (защищает от сюрпризов – например,
Перегрузка	
  операторов
Прежде	
  чем	
  начать
• Это	
  механизм,	
  при	
  неумелом	
  использовании	
  
которого	
  можно	
  полностью	
  запутать	
  код.
• Непонятный	
  код	
  – причина	
  сложных	
  ошибок!
• Перегруженные	
  операции	
  помогают	
  
определить	
  «свойства»	
  созданного	
  вами	
  
класса,	
  но	
  не	
  алгоритма	
  работы	
  с	
  классами!
Перегрузка	
  операций
Можно	
  описать	
  функции,	
  для	
  описания	
  следующих	
  операций:
+	
  -­‐ *	
  /	
  %	
  ^	
  &	
  |	
  ~	
  !
=	
  <	
  >	
  +=	
  -­‐=	
  *=	
  /=	
  %=	
  ^=	
  &=
|=	
  <<	
  >>	
  >>=	
  <<=	
  ==	
  !=	
  <=	
  >=	
  &&
||	
  ++	
  -­‐-­‐ -­‐>*	
  ,	
  -­‐>	
  []	
  ()	
  new	
  delete
Нельзя	
  изменить	
  приоритеты	
  этих	
  операций,	
  равно	
  как	
  и	
  синтаксические	
  правила	
  для	
  
выражений.	
  Так,	
  нельзя	
  определить	
  унарную	
  операцию	
  %	
  ,	
  также	
  как	
  и	
  бинарную	
  
операцию	
  !.
Синтаксис
type operator operator-symbol ( parameter-list )
Ключевое слово operator позволяет перегружать операции. Например:
• Перегрузка	
  унарных	
  операторов:
◦ ret-­‐type operatorop ( arg )
◦ где	
  ret-­‐type и	
  op соответствуют	
  описанию	
  для	
  функций-­‐членов	
  операторов,	
   а	
  arg — аргумент	
  типа	
  
класса,	
  с	
  которым	
  необходимо	
  выполнить	
  операцию.
• Перегрузка	
  бинарных	
  операторов
◦ ret-­‐type operatorop( arg1, arg2 )	
  
◦ где	
  ret-­‐type и	
  op — элементы,	
  описанные	
  для	
  функций	
  операторов	
  членов,	
  а	
  arg1	
  и	
  arg2	
  —
аргументы.	
  Хотя	
  бы	
  один	
  из	
  аргументов	
  должен	
  принадлежать	
  типу	
  класса.	
  
Пример
Example16_Operator
1.class Rectangle {
2.public:
3. Rectangle(int,int);
4. int operator[](int i);
5. operator int();
6. void print();
7. virtual ~Rectangle();
8.private:
9. int _width,_height;
10.};
Префиксные	
  и	
  постфиксные	
  операторы
++	
  и	
  -­‐-­‐
Операторы	
  инкремента	
  и	
  декремента	
  относятся	
  к	
  особой	
  категории,	
  поскольку	
  имеется	
  два	
  варианта	
  
каждого	
  из	
  них:	
  
• преинкрементный	
  и	
  постинкрементный	
  операторы;	
  
• предекрементный	
  и	
  постдекрементный	
  операторы.	
  
При	
  написании	
  функций	
  перегруженных	
  операторов	
  полезно	
  реализовать	
  отдельные	
  версии	
  для	
  
префиксной	
  и	
  постфиксной	
  форм	
  этих	
  операторов.	
  Для	
  различения	
  двух	
  вариантов	
  используется	
  
следующее	
  правило:	
  префиксная форма	
  оператора	
  объявляется	
  точно	
  так	
  же,	
  как	
  и	
  любой	
  другой	
  унарный	
  
оператор;	
  в	
  постфиксной форме	
  принимается	
  дополнительный	
  аргумент	
  типа	
  int.	
  
Пример:
friend Point& operator++( Point& ) // Prefix increment
friend Point& operator++( Point&, int ) // Postfix increment
friend Point& operator--( Point& ) // Prefix decrement
friend Point& operator--( Point&, int ) // Postfix decrement
Пример
Example17_OperatorPlus
1.class Rectangle {
2.public:
3. Rectangle(int,int);
4. Rectangle& operator++();
5. Rectangle& operator++(int);
6. int operator[](int i);
7. operator int();
8. void print();
9. virtual ~Rectangle();
10.private:
11. int _width,_height;
12.};
Бинарные	
  операторы
Example18_BinaryOperator
1.class Rectangle {
2.public:
3. Rectangle(int,int);
4. Rectangle& operator++();
5. Rectangle& operator++(int);
6. int operator[](int i);
7. operator int();
8. friend std::ostream& operator <<(std::ostream &os,Rectangle &rec);
9. friend Rectangle operator +(Rectangle &left, Rectangle &right);
1. virtual ~Rectangle();
2.private:
3. int _width,_height;
4.};
Переопределение	
  оператора	
  
присваивания
Example19_OperatorAssign
Он	
  должен	
  быть	
  нестатической	
  функцией-­‐членом.	
  Никакой	
  оператор	
  operator= не	
  может	
  
быть	
  объявлен	
  как	
  функция,	
  не	
  являющаяся	
  членом.	
  
Он	
  не	
  наследуется	
  производными	
  классами.	
  
Компилятор	
  может	
  создавать	
  для	
  типов	
  классов	
  функции	
  operator= по	
  умолчанию,	
  если	
  
они	
  не	
  существуют.	
   В	
  этом	
  случае	
  оператор	
  равно	
  применяется	
  к	
  каждому	
  члену	
  класса.
Спецификатор	
  delete и	
  default
Example27_Delete
Иногда	
  очень	
  важно	
  сделать	
  так,	
  что	
  бы	
  у	
  объекта	
  был	
  только	
  один	
  экземпляр.	
  Т.е.,	
  что	
  бы	
  его	
  нельзя	
  было	
  
скопировать.
Сейчас	
  стандартная	
  идиома	
  «запрещения	
  копирования»	
  может	
  быть	
  явно	
  выражена	
  следующим	
  образом:
class X {
// ...
X& operator=(const X&) = delete; // Запрет копирования
X(const X&) = delete; // запрет копирование в момент конструирования
};
Такая	
  конструкция	
  запрещает	
  компилятору	
  «создавать»	
  конструкторы	
  и	
  оператор	
  копирования	
  «по	
  умолчанию».	
  
Ключевое	
  слово	
  =default,	
  наоборот,	
  указывает	
  что	
  мы	
  хотим	
  что	
  бы	
  компилятор	
  использовал	
  операцию	
  «по-­‐
умолчанию».	
  Вообще	
  говоря,	
  она	
  является	
  избыточной.
Делаем	
  функтор
CPP_Examples21_OperatorFunctor
Функторы	
  в	
  C++	
  являются	
  сокращением	
  от	
  "функциональные	
  объекты".	
  Функциональный	
  объект	
  является	
  
экземпляром	
  класса	
  С++,	
  в	
  котором	
  определён	
  operator().	
  Если	
  вы	
  определите	
  operator() для	
  C++	
  класса,	
  то	
  
вы	
  получите	
  объект,	
  который	
  действует	
  как	
  функция,	
  но	
  может	
  также	
  хранить	
  состояние.
class A{
private:
int _value;
public: A(int a) : _value(a) {};
A operator()(int a) {
std::cout << _value+a << std::endl;
return A(_value+a);
}
};
Литералы
Литерал — это	
  некоторое	
  выражение,	
  создающее	
  объект.	
  В	
  языке	
  С++	
  существуют	
  
литералы	
  для	
  разных	
  встроенных	
  типов	
  (2.14	
  Literals):
123	
  	
  	
  	
  //	
  int
1.2	
  	
  	
  	
  //	
  double
1.2F	
  	
  	
  	
  //	
  float
'a'	
  	
  	
  	
  //	
  char
1ULL	
  	
  	
  	
  //	
  unsigned	
  long	
  long
0xD0	
  	
  	
  	
  //	
  unsigned	
  int в	
  шестнадцатеричном	
  формате
"as"	
  	
  	
  	
  //	
  string
Пользовательские	
  литералы
Example22_Literal
Должны	
  начинаться	
  с	
  подчеркивания:
OutputType operator "" _suffix(unsigned long long);
Конструктор	
  типа	
  должен	
  так	
  же	
  иметь	
  спецификатор	
  constexpr
Могут	
  иметь	
  следующие	
  параметры:
const char*
unsigned long long int
long double
char
wchar_t
char16_t
char32_t
const char*, std::size_t
const wchar_t*, std::size_t
const char16_t*, std::size_t
const char32_t*, std::size_t
Спасибо!
ВСЕ	
  ИДЕМ	
  НА	
  ПЕРЕРЫВ

Más contenido relacionado

La actualidad más candente

Python и его тормоза
Python и его тормозаPython и его тормоза
Python и его тормозаAlexander Shigin
 
Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование Sergey Schetinin
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Sergey Platonov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типовcorehard_by
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.Igor Shkulipa
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and catscorehard_by
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Yandex
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Dima Dzuba
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli typesmcroitor
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++mcroitor
 

La actualidad más candente (20)

JRebel
JRebelJRebel
JRebel
 
Python и его тормоза
Python и его тормозаPython и его тормоза
Python и его тормоза
 
Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Bytecode
BytecodeBytecode
Bytecode
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli types
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 

Similar a Объектно-Ориентированное Программирование на C++, Лекции 3 и 4

C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному кодуVasiliy Deynega
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Yandex
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4Technopark
 
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CГлеб Тарасов
 
Ecma script 6 in action
Ecma script 6 in actionEcma script 6 in action
Ecma script 6 in actionYuri Trukhin
 
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий solit
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокAndrey Karpov
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9Technopark
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.Igor Shkulipa
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
javascript
javascriptjavascript
javascriptsovest
 
javascript_part1
javascript_part1javascript_part1
javascript_part1sovest
 
Михаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияМихаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияYandex
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxYandex
 

Similar a Объектно-Ориентированное Программирование на C++, Лекции 3 и 4 (20)

C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4
 
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
 
Ecma script 6 in action
Ecma script 6 in actionEcma script 6 in action
Ecma script 6 in action
 
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
javascript
javascriptjavascript
javascript
 
javascript_part1
javascript_part1javascript_part1
javascript_part1
 
Михаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияМихаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знания
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajax
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 

Más de Dima Dzuba

Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16Dima Dzuba
 
Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14Dima Dzuba
 
Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12Dima Dzuba
 
Requirement modelling in software creation process
Requirement modelling in software creation processRequirement modelling in software creation process
Requirement modelling in software creation processDima Dzuba
 
Модифицируемость программных систем
Модифицируемость программных системМодифицируемость программных систем
Модифицируемость программных системDima Dzuba
 
Производительность программных систем
Производительность программных системПроизводительность программных систем
Производительность программных системDima Dzuba
 
Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7Dima Dzuba
 
Решение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных системРешение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных системDima Dzuba
 
Arch intro4sts
Arch intro4stsArch intro4sts
Arch intro4stsDima Dzuba
 
Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Dima Dzuba
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Dima Dzuba
 
Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Dima Dzuba
 
Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Dima Dzuba
 

Más de Dima Dzuba (20)

Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16
 
Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14
 
Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12
 
Requirement modelling in software creation process
Requirement modelling in software creation processRequirement modelling in software creation process
Requirement modelling in software creation process
 
Модифицируемость программных систем
Модифицируемость программных системМодифицируемость программных систем
Модифицируемость программных систем
 
Производительность программных систем
Производительность программных системПроизводительность программных систем
Производительность программных систем
 
Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01
 
МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6
 
МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5
 
МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4
 
МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3
 
МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2
 
МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1
 
МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7
 
Решение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных системРешение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных систем
 
Arch intro4sts
Arch intro4stsArch intro4sts
Arch intro4sts
 
Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9
 
Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8
 
Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7
 

Объектно-Ориентированное Программирование на C++, Лекции 3 и 4

  • 2. 7.  сохраняемость Сохраняемость -­‐ способность  объекта  существовать  во  времени,  переживая   породивший  его  процесс,  и  (или)  в  пространстве,  перемещаясь  из  своего   первоначального  адресного  пространства.
  • 3. Как  передать  объект  на  другую   машину? 3
  • 4. А  что  если  объект  сложный? граф  объектов Задача  сериализации объекта,  включающего  только  поля  из  элементарных  типов  значений   и  строк,  не  представляет  принципиальных  трудностей.  Для  такого  объекта  в  ходе   сериализации в  поток  записываются  сами  значения  всех  полей  объекта.  Однако  в  общем   случае  объект  содержит  ссылки  на  другие  объекты,  которые,  в  свою  очередь,  могут   ссылаться  друг  на  друга,  образуя  так  называемый  граф  объектов  (object graph).   4 class SampleClass { SampleClass fieldA = nullptr; SampleClass fieldB = nullptr; } ... SampleClass root = new SampleClass(); SampleClass child1 = new SampleClass(); SampleClass child2 = new SampleClass(); root.fieldA = child1; root.fieldB = child2; child1.fieldA = child2;
  • 5. Просто  пронумеруем  объекты почти  как  ссылки  в  C++ 1. ObjectID ? В  ходе  сериализации объектам  должны  быть  поставлены  в  соответствие  некоторые   идентификаторы,  и  в  хранилище  отдельно  сохраняется  список  объектов,  отмеченный   идентификаторами,  а  при  сериализации вместо  ссылок  записываются  идентификаторы   ссылаемых  объектов. 2. Виртуальный  адрес! В  программе  роль  идентификатора  объекта  выполняет  его  адрес,  но  вместо  него  обычно   удобнее  назначить  некоторые  идентификаторы  в  процедуре  сериализации для  более   легкого  чтения  человеком  полученного  образа. 3. Hash-­‐map  … В  ходе  сериализации нужно  ввести  список  адресов  уже  записанных  объектов,  как  для   ведения  списка  идентификаторов,  так  и  для  обнаружения  возможных  циклов  при   обходе  графа  методом  в  глубину. 5
  • 6. Пример Example14_Serialize 1. class A { 2. public: 3. A(const char* value) : next(nullptr), name(value) {}; 4. A(std::ifstream &is) { 5. bool is_next; 6. is >> name; 7. is >> is_next; 8. if (is_next) next = new A(is);} 9. void Serialize(std::ofstream &os) { 10. os << name << std::endl; 11. if (next != nullptr) { 12. os << true; 13. next->Serialize(os);} else os << false;} 14. void SetNext(A* value) { 15. next = value; } 16. virtual ~A() { delete next; } 17.private: 18. std::string name; 19. A* next; 20.};
  • 7. Полезные  приемы  по  работе  с  классами
  • 8. Временные  объекты Вре́менные объекты — в  C++  объекты,   которые  компилятор  создаёт  автоматически   по  ходу  вычисления  выражений.  Такие   объекты  не  имеют  имени  и  уничтожаются   сразу  же,  как  только  в  них  исчезает   потребность. Пример: string r = string("1") + "2" + "3"; string r, tmp1, tmp2, tmp3; tmp1.ctor("1"); tmp2.ctor(); tmp2 = tmp1 + "2"; tmp3.ctor(); tmp3 = tmp2 + "3"; r.ctor(tmp3); tmp3.dtor(); tmp2.dtor(); tmp1.dtor();
  • 9. Модификаторы  функций Example15_Virtual Ключевое  слово virtual опционально  и  поэтому  немного  затрудняло  чтение  кода,  заставляя   вечно  возвращаться  в  вершину  иерархии  наследования,  чтобы  посмотреть  объявлен  ли   виртуальным  тот  или  иной  метод. Типовые  ошибки: Изменение  сигнатуры  метода  в  наследнике. Модификатор  override позволяет  указать  компилятору,  что  мы  хотим  переопределить   виртуальный  метод.  Если  мы  ошиблись  в  описании  сигнатуры  метода  – то  компилятор   выдаст  нам  ошибку.  Этот  модификатор  влияет  только  на  проверки  в  момент  компиляции.
  • 10. Модификатор  final Example28_Final Модификатор  final,  указывающий  что  производный  класс  не  должен  переопределять   виртуальный  метод. Работает  только  с  модификатором  virtual.  Т.е.  Создавать  «копию»  функции  в  классе-­‐ наследнике  с  помощью  этой  техники  запретить  нельзя. Применяется,  в  случае  если  нужно  запретить  дальнейшее  переопределение  метода  в   дальнейших  наследниках  наследника  (очевидно,  что  в  родительском  классе  такой   модификатор  ставить  бессмысленно).
  • 11. Модификатор  const Example29_Const сonst,  применительно  к  методу  (например,  void  foo  const {})  означает,  что  метод  не  может   вызывать  другие  методы  без  модификатора  const и  не  может  менять  значения  атрибутов   объекта. class A{ int a; void fooA2() {} void fooA () const{ fooA2(); //ошибка a=7; // ошибка }
  • 12. mutable Example33_Mutable Ключевое  слово  mutable позволяет  специфицировать   атрибуты  класса,  которые  могут  меняться  из  const методов. Иногда  необходимо  иметь  такие  атрибуты  для   «служебных  целей»,  например,  подсчитывать  число   обращений  к  методу  и  т.д.
  • 13. Const Example23_Const 1. int a=100;//два обычных объекта типа int 2. int b=222; 3. int *const P2=&a; //Константный указатель 4. *P2=987; //Менять значение разрешено 5. //P2=&b; //Но изменять адрес не разрешается 6. const int *P1=&a; //Указатель на константу 7. //*P1=110; //Менять значение нельзя 8. P1=&b; //Но менять адрес разрешено 9. const int *const P3=&a;//Константный указатель на константу 10.//*P3=155; //Изменять нельзя ни значение 11.//P3=&b; //Ни адрес к которому такой указатель привязан
  • 14. Constexpr Example31_constexpr Позволяет  создавать  выражения,  вычисляемые  на  этапе  компиляции  (позволяет  упростить  код).   Ключевое  слово  constexpr,  добавленное  в  C++11,  перед  функцией  означает,  что  если  значения   параметров  возможно  посчитать  на  этапе  компиляции,  то  возвращаемое  значение  также   должно  посчитаться  на  этапе  компиляции.  Если  значение  хотя  бы  одного  параметра  будет   неизвестно  на  этапе  компиляции,  то  функция  будет  запущена  в  runtime (а  не  будет  выведена   ошибка  компиляции). constexpr int sum (int a, int b){ return a + b; } void func(){ constexpr int c = sum (5, 12); // значение переменной будет посчитано на этапе компиляции }
  • 15. Inheritance  /  наследование Example24_MultipleInheritance class temporary { /* ... */ }; class secretary : public employee { /* ... */ }; class tsec : public temporary, public secretary { /* ... */ }; class consultant : public temporary, public manager { /* ... */ }; В  С++  в  отличии  от  большинства  других   объектно-­‐ориентированных  языков  есть   множественное  наследование! Очень  плохо,  если  у  двух  родителей  класса   есть  общий  родитель!
  • 16. Ссылка  на  себя Считается,  что  в  каждой  функции-­‐члене   класса  X  указатель  this описан  неявно  как X *const this; class X { int m; public: int readm() { return this->m; } };
  • 17. Ссылка  на  родителя Example25_ReferenceToParent class Parent { public: Parent(void); ~Parent(void); void Foo(void); }; class Child : public Parent { public: Child(void); ~Child(void); void Foo(void); }; void Parent::Foo(void) { std::cout << "Parentn"; } void Child::Foo(void) { Parent::Foo(); std::cout << "Childn"; }
  • 18. Виртуальные  деструкторы Example26_VirtualDestructor C++  вызывает  деструктор  для  текущего  типа  и  для  всех  его  родителей. Однако,  если  мы  работаем  с  указателями  то  можем  попасть  в  неприятную  ситуацию,  когда   вызываем  оператор  delete  у  указателя,  предварительно  приведя  его  к  типу  родителя.  В   этом  случае,  вообще  говоря,  у  наследников  деструктор  вызван  не  будет (например,  если  у   родителя  нет  деструктора). Однако  если  объявить  деструктор  базового  класса  как  virtual  то  будут  вызваны  деструкторы   всех  классов. Всегда  объявляй  деструктор  как  virtual!
  • 19. Последовательность  вызова  конструкторов   и  деструкторов Конструкторы  вызываются  начиная  от  родителя  к  наследнику. Деструкторы  вызываются  начиная  от  наследника  к  родителю. class A {} class B : A {} class C: B{} Конструкторы: A, B, C Деструкторы: ~C, ~B,~A
  • 20. Явные  и  неявные  конструкторы Example20_explicit   В  С++  существуют  явные  и  неявные  конструкторы;  преобразования,  определенные  с  помощью  конструктора  со   спецификатором  explicit могут  использоваться  только  при  явном  преобразовании,  в  то  время,  как  другие   конструкторы  могут  использоваться  также  и  в  неявных  преобразованиях.   Например: // "обычный конструктор" определяет неявное преобразование class A { S(int); }; A a1(1); // ok A a2 = 1; // ok void Foo(A); Foo(1); // ok (но это может привести к неприятным class E { explicit E(int); }; // явный конструктор E e1(1); // ok E e2 = 1; // ошибка (хотя это обычно является сюрпризом) void f(E); f(1); // ошибка (защищает от сюрпризов – например,
  • 22. Прежде  чем  начать • Это  механизм,  при  неумелом  использовании   которого  можно  полностью  запутать  код. • Непонятный  код  – причина  сложных  ошибок! • Перегруженные  операции  помогают   определить  «свойства»  созданного  вами   класса,  но  не  алгоритма  работы  с  классами!
  • 23. Перегрузка  операций Можно  описать  функции,  для  описания  следующих  операций: +  -­‐ *  /  %  ^  &  |  ~  ! =  <  >  +=  -­‐=  *=  /=  %=  ^=  &= |=  <<  >>  >>=  <<=  ==  !=  <=  >=  && ||  ++  -­‐-­‐ -­‐>*  ,  -­‐>  []  ()  new  delete Нельзя  изменить  приоритеты  этих  операций,  равно  как  и  синтаксические  правила  для   выражений.  Так,  нельзя  определить  унарную  операцию  %  ,  также  как  и  бинарную   операцию  !.
  • 24. Синтаксис type operator operator-symbol ( parameter-list ) Ключевое слово operator позволяет перегружать операции. Например: • Перегрузка  унарных  операторов: ◦ ret-­‐type operatorop ( arg ) ◦ где  ret-­‐type и  op соответствуют  описанию  для  функций-­‐членов  операторов,   а  arg — аргумент  типа   класса,  с  которым  необходимо  выполнить  операцию. • Перегрузка  бинарных  операторов ◦ ret-­‐type operatorop( arg1, arg2 )   ◦ где  ret-­‐type и  op — элементы,  описанные  для  функций  операторов  членов,  а  arg1  и  arg2  — аргументы.  Хотя  бы  один  из  аргументов  должен  принадлежать  типу  класса.  
  • 25. Пример Example16_Operator 1.class Rectangle { 2.public: 3. Rectangle(int,int); 4. int operator[](int i); 5. operator int(); 6. void print(); 7. virtual ~Rectangle(); 8.private: 9. int _width,_height; 10.};
  • 26. Префиксные  и  постфиксные  операторы ++  и  -­‐-­‐ Операторы  инкремента  и  декремента  относятся  к  особой  категории,  поскольку  имеется  два  варианта   каждого  из  них:   • преинкрементный  и  постинкрементный  операторы;   • предекрементный  и  постдекрементный  операторы.   При  написании  функций  перегруженных  операторов  полезно  реализовать  отдельные  версии  для   префиксной  и  постфиксной  форм  этих  операторов.  Для  различения  двух  вариантов  используется   следующее  правило:  префиксная форма  оператора  объявляется  точно  так  же,  как  и  любой  другой  унарный   оператор;  в  постфиксной форме  принимается  дополнительный  аргумент  типа  int.   Пример: friend Point& operator++( Point& ) // Prefix increment friend Point& operator++( Point&, int ) // Postfix increment friend Point& operator--( Point& ) // Prefix decrement friend Point& operator--( Point&, int ) // Postfix decrement
  • 27. Пример Example17_OperatorPlus 1.class Rectangle { 2.public: 3. Rectangle(int,int); 4. Rectangle& operator++(); 5. Rectangle& operator++(int); 6. int operator[](int i); 7. operator int(); 8. void print(); 9. virtual ~Rectangle(); 10.private: 11. int _width,_height; 12.};
  • 28. Бинарные  операторы Example18_BinaryOperator 1.class Rectangle { 2.public: 3. Rectangle(int,int); 4. Rectangle& operator++(); 5. Rectangle& operator++(int); 6. int operator[](int i); 7. operator int(); 8. friend std::ostream& operator <<(std::ostream &os,Rectangle &rec); 9. friend Rectangle operator +(Rectangle &left, Rectangle &right); 1. virtual ~Rectangle(); 2.private: 3. int _width,_height; 4.};
  • 29. Переопределение  оператора   присваивания Example19_OperatorAssign Он  должен  быть  нестатической  функцией-­‐членом.  Никакой  оператор  operator= не  может   быть  объявлен  как  функция,  не  являющаяся  членом.   Он  не  наследуется  производными  классами.   Компилятор  может  создавать  для  типов  классов  функции  operator= по  умолчанию,  если   они  не  существуют.   В  этом  случае  оператор  равно  применяется  к  каждому  члену  класса.
  • 30. Спецификатор  delete и  default Example27_Delete Иногда  очень  важно  сделать  так,  что  бы  у  объекта  был  только  один  экземпляр.  Т.е.,  что  бы  его  нельзя  было   скопировать. Сейчас  стандартная  идиома  «запрещения  копирования»  может  быть  явно  выражена  следующим  образом: class X { // ... X& operator=(const X&) = delete; // Запрет копирования X(const X&) = delete; // запрет копирование в момент конструирования }; Такая  конструкция  запрещает  компилятору  «создавать»  конструкторы  и  оператор  копирования  «по  умолчанию».   Ключевое  слово  =default,  наоборот,  указывает  что  мы  хотим  что  бы  компилятор  использовал  операцию  «по-­‐ умолчанию».  Вообще  говоря,  она  является  избыточной.
  • 31. Делаем  функтор CPP_Examples21_OperatorFunctor Функторы  в  C++  являются  сокращением  от  "функциональные  объекты".  Функциональный  объект  является   экземпляром  класса  С++,  в  котором  определён  operator().  Если  вы  определите  operator() для  C++  класса,  то   вы  получите  объект,  который  действует  как  функция,  но  может  также  хранить  состояние. class A{ private: int _value; public: A(int a) : _value(a) {}; A operator()(int a) { std::cout << _value+a << std::endl; return A(_value+a); } };
  • 32. Литералы Литерал — это  некоторое  выражение,  создающее  объект.  В  языке  С++  существуют   литералы  для  разных  встроенных  типов  (2.14  Literals): 123        //  int 1.2        //  double 1.2F        //  float 'a'        //  char 1ULL        //  unsigned  long  long 0xD0        //  unsigned  int в  шестнадцатеричном  формате "as"        //  string
  • 33. Пользовательские  литералы Example22_Literal Должны  начинаться  с  подчеркивания: OutputType operator "" _suffix(unsigned long long); Конструктор  типа  должен  так  же  иметь  спецификатор  constexpr Могут  иметь  следующие  параметры: const char* unsigned long long int long double char wchar_t char16_t char32_t const char*, std::size_t const wchar_t*, std::size_t const char16_t*, std::size_t const char32_t*, std::size_t