13
Дополнительные возможности C++

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

Embed Size (px)

DESCRIPTION

Дополнительные возможности C++

Citation preview

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

Дополнительные возможности C++

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

ConstCPP_Examples12

int a=100;//два обычных объекта типа int

int b=222;

int *const P2=&a; //Константный указатель

*P2=987; //Менять значение разрешено

//P2=&b; //Но изменять адрес не разрешается

const int *P1=&a; //Указатель на константу

//*P1=110; //Менять значение нельзя

P1=&b; //Но менять адрес разрешено

const int *const P3=&a;//Константный указатель на константу

//*P3=155; //Изменять нельзя ни значение

//P3=&b; //Ни адрес к которому такой указатель привязан

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

Временные объектыВре́менные объекты — в 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();

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

RvalueCPP_Examples04_5

В C++11 появился новый тип ссылки —rvalue-ссылка (англ. rvalue reference).

Его объявление следующее: type &&.

Новые правила разрешения перегрузки позволяют использовать разные перегруженные функции для неконстантных временных объектов, обозначаемых посредством rvalues, и для всех остальных объектов.

Данное нововведение позволяет реализовывать семантику переноса (Movesemantics).

class Print

{

public:

Print(std::string &a) {

std::cout << "Reference:" << a

<< std::endl; }

Print(std::string &&a) {

std::cout << "RValue:" << a <<

std::endl; }

};

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

Что нового в C++: range-based циклыCPP_Examples04_3

В С++11 была добавлена поддержка парадигмы foreach для итерации по набору. В новой форме возможно выполнять итерации в случае, если для объекта итерации перегружены методы begin() и end().

Данный циклы не работают с массивами, аллоцируемыми динамически (т.к. про них компилятор не знает, какой у них будет размер). А вот с такими работает:

int arr[] = { 1, 2, 3, 4, 5 };

for (auto e : arr)

Std::cout << e << std::endl;

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

Ключевое слово overrideCPP_Examples061Ключевое слово virtual опционально и поэтому немного затрудняло чтение кода, заставляя вечно возвращаться в вершину иерархии наследования, чтобы посмотреть объявлен ли виртуальным тот или иной метод.

Типовые ошибки: Изменение сигнатуры метода в наследнике.

Были добавлены два новых идентификатора (не ключевые слова):

• override, для указания того, что метод является переопределением виртуального метода в базовом классе

• final, указывающий что производный класс не должен переопределять виртуальный метод.

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

Inheritance / наследованиеCPP_Examples071

class temporary { /* ... */ };

class secretary : public

employee { /* ... */ };

class tsec

: public temporary, public

secretary { /* ... */ };

class consultant

: public temporary, public

manager { /* ... */ };

В С++ в отличии от большинства других объектно-ориентированных языков есть множественное наследование!

Очень плохо, если у двух родителей класса есть общий родитель!

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

Еще раз о конструкторахclass employee {

// ...

public:

// ...

employee(char* n, int d);

};

class manager : public employee {

// ...

public:

// ...

manager(char* n, int i, int d);

};

manager::manager(char* n, int l, int d)

: employee(n,d), // вызов родителя

level(l), // аналогично level=l

group(0)

{

}

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

Ссылка на себяСчитается, что в каждой функции-члене класса X указатель this описан неявно как

X *const this;

class X {

int m;

public:

int readm() { return this->m; }

};

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

Ссылка на родителяCPP_Examples07

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 << "Parent\n";

}

void Child::Foo(void)

{

Parent::Foo();

std::cout << "Child\n";

}

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

Виртуальные деструкторыCPP_Examples071_VDestructorC++ вызывает деструктор для текущего типа и для всех его родителей.

Однако, если мы работаем с указателями то можем попасть в неприятную ситуацию, когда вызываем оператор delete у указателя, предварительно приведя его к типу родителя. В этом случае у наследников деструктор вызван не будет.

Однако если объявить деструктор базового класса как virtual то будут вызваны деструкторы всех классов.

Всегда объявляй деструктор как virtual!

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

Умные указатели std::shared_ptrCPP_Examples07_2SharedPtr

Хранит указатель на объект.

Предоставляет некоторое подобие функциональности «Сборщика мусора»

Позволяет брать во владение указатель на объект и отпускать его.

Как только указателем на объект ни кто не владеет – он удаляется.

swap – позволяет обмениваться указателями на объекты

reset – позволяет уменьшать количество ссылок на объект.

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

Перекрестные ссылки и std:shared_ptrCPP_Examples07_3SharedPtr_LoopЕсли зациклить объекты друг на друга, то появится «цикл» и объект ни когда не удалится! Т.к. деструктор не запустится!

A B

shared_ptr<A> shared_ptr<B>

shared_ptr<A>shared_ptr<B>