Upload
dima-dzuba
View
577
Download
19
Embed Size (px)
DESCRIPTION
Дополнительные возможности C++
Citation preview
Дополнительные возможности C++
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; //Ни адрес к которому такой указатель привязан
Временные объектыВре́менные объекты — в 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();
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; }
};
Что нового в 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;
Ключевое слово overrideCPP_Examples061Ключевое слово virtual опционально и поэтому немного затрудняло чтение кода, заставляя вечно возвращаться в вершину иерархии наследования, чтобы посмотреть объявлен ли виртуальным тот или иной метод.
Типовые ошибки: Изменение сигнатуры метода в наследнике.
Были добавлены два новых идентификатора (не ключевые слова):
• override, для указания того, что метод является переопределением виртуального метода в базовом классе
• final, указывающий что производный класс не должен переопределять виртуальный метод.
Inheritance / наследованиеCPP_Examples071
class temporary { /* ... */ };
class secretary : public
employee { /* ... */ };
class tsec
: public temporary, public
secretary { /* ... */ };
class consultant
: public temporary, public
manager { /* ... */ };
В С++ в отличии от большинства других объектно-ориентированных языков есть множественное наследование!
Очень плохо, если у двух родителей класса есть общий родитель!
Еще раз о конструкторах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)
{
}
Ссылка на себяСчитается, что в каждой функции-члене класса X указатель this описан неявно как
X *const this;
class X {
int m;
public:
int readm() { return this->m; }
};
Ссылка на родителя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";
}
Виртуальные деструкторыCPP_Examples071_VDestructorC++ вызывает деструктор для текущего типа и для всех его родителей.
Однако, если мы работаем с указателями то можем попасть в неприятную ситуацию, когда вызываем оператор delete у указателя, предварительно приведя его к типу родителя. В этом случае у наследников деструктор вызван не будет.
Однако если объявить деструктор базового класса как virtual то будут вызваны деструкторы всех классов.
Всегда объявляй деструктор как virtual!
Умные указатели std::shared_ptrCPP_Examples07_2SharedPtr
Хранит указатель на объект.
Предоставляет некоторое подобие функциональности «Сборщика мусора»
Позволяет брать во владение указатель на объект и отпускать его.
Как только указателем на объект ни кто не владеет – он удаляется.
swap – позволяет обмениваться указателями на объекты
reset – позволяет уменьшать количество ссылок на объект.
Перекрестные ссылки и std:shared_ptrCPP_Examples07_3SharedPtr_LoopЕсли зациклить объекты друг на друга, то появится «цикл» и объект ни когда не удалится! Т.к. деструктор не запустится!
A B
shared_ptr<A> shared_ptr<B>
shared_ptr<A>shared_ptr<B>