особенности программирования на с++

20
ОСОБЕННОСТИ ПРОГРАММИРОВАНИЯ НА С++ Кройтор Михаил

Upload: mcroitor

Post on 23-Dec-2014

4.629 views

Category:

Education


3 download

DESCRIPTION

очень кратко о возможностях языка с++, которые необходимо знать перед изучением устройства стандартной библиотеки с++

TRANSCRIPT

Page 1: особенности программирования на с++

ОСОБЕННОСТИ ПРОГРАММИРОВАНИЯ НА С++

Кройтор Михаил

Page 2: особенности программирования на с++

Содержание

Указатель на функцию Наследование Виртуальные функции

Полиморфизм на основе виртуальных функций Абстрактные классы

Перегрузка операций Функциональные объекты Шаблоны

Статический полиморфизм Специализация шаблонов

Некоторые особенности стандарта C++11

Page 3: особенности программирования на с++

Указатель на функцию

Указателем на функцию называется адрес точки входа функции.

Объявление переменной - указателя на функцию:

void (*pfunc)(double*, const size_t); Объявление типа указателя на

функцию:typedef void (*pfunc_t)(double*, const

size_t);

Page 4: особенности программирования на с++

Указатель на функцию: пример

#include <stdio.h>typedef void (*event_t)(void*, void*);

struct Button{    size_t x, y, width, height;    char text[255];    event_t OnClick;};

void ButtonPressed(void* /*sender*/, void* /*arg*/){    puts("button pressed!");}

int main(){    Button btn = {5, 5, 75, 30, "Press Me!", ButtonPressed};    btn.OnClick();    return 0;}

Page 5: особенности программирования на с++

Наследование

Наследование – механизм, позволяющий описать новый класс (потомок, наследник, производный класс) на основе существующего (предок, базовый класс, родительский класс), с сохранением функциональности родительского класса.

Наследование позволяет обращаться с производными классами так же, как и с их родительскими классами.

Указатель на объект базового класса может ссылаться и на объект производного класса. Обратное утверждение неверно.

class Base {

int value;

public:

Base(): value(0){}

int getValue() { return value; }

};

class Derived: public Base{

public:

Derived() : Base() {}

void setValue(int data) {

value = data;

}

};

Пример наследования:

Page 6: особенности программирования на с++

Наследование: пример использования

class Entity{protected:

std::string name;Entity* parent;

public:virtual std::string ToString() const = 0;Entity* GetParent() const{ return parent; }

};

class Folder: public Entity{std::list<Entity*> childs;

public:Folder(std::string n, Entity* p): name(n), parent(p){}std::string ToString() const { return name; }

};

Page 7: особенности программирования на с++

Виртуальные функции

Виртуальной функцией класса называют метод, который может быть переопределён в потомке таким образом, что конкретная реализация функции для вызова будет определяться во время исполнения.

Виртуальные функции являются одной из основ реализации динамического полиморфизма.

class Base{public: Base(): value(0){} virtual void show() { std::cout << "Base" << std::endl; }}; class Derived: public Base{public: Derived() : Base() {} virtual void show() { std::cout << «Derived" << std::endl; }};

Пример:

Page 8: особенности программирования на с++

Виртуальные функции:пример полиморфизма

class Base{public: Base(): value(0){} virtual void show() { std::cout << "Base" << std::endl; }}; class Derived: public Base{public: Derived() : Base() {} virtual void show() { std::cout << "Derived" << std::endl; }}; void print(Base* p) { p->show(); } int main(){ Base* b = new Base(); Derived* d = new Derived();  print(b); print(d); return 0;}

Page 9: особенности программирования на с++

Виртуальные функции:абстрактные классы

Если базовый класс только декларирует существование виртуального метода, но не предполагает его реализации, то такой метод называется чистым виртуальным или абстрактным.

Класс, содержащий хотя бы один абстрактный метод, называется абстрактным классом.

Любая абстрактная функция должна быть определена в дочернем классе.

Абстрактные классы используются в том случае, когда программист хочет определить семейство классов с одинаковым поведением.

struct Shape{virtual void Draw() = 0;virtual void Hide() = 0;

};struct Point: Shape{

virtual void Draw(){ // draw this point

}virtual void Hide(){ // hide this point}

};Абстрактные классы очень похожина интерфейсы из Java и C#

Page 10: особенности программирования на с++

Перегрузка операций

полезно переопределить некоторый оператор для класса, тогда запись программы становится более компактной и понятной.

Общая форма определения оператора выглядит следующим образом:

<return_type> operator <operator_sign> (<operator_parametres>);

сlass int_pair{    int first, second;public:    int_pair(int f = 0, int s = 0): first(f), second(s) {}    bool operator == (const int_pair& p) const {        return (first == p.first) && (second == p.second);    }};

bool operator != (const int_pair& p1, const int_pair& p2){    return !(p1 == p2);}

для определения, где лучше всего определить оператор - внутри класса или вне его, - спросите себя, изменяет ли этот оператор свои входные параметры. Если изменяет - то этот оператор - часть класса. Если не изменяет, то оператор лучше всего определить вне класса.

Page 11: особенности программирования на с++

Функциональные объекты

Если в классе переопределен оператор (), то объекты этого класса получают свойства функций (их можно использовать как функции). Такие объекты называются функциональными или функторами.

Функторы удобно использовать, когда функция должна обладать "памятью", а также, как замена указателей на функции.

// функтор, подсчитывающих количество вызовов

class _swap{    static size_t counter = 0;    static void increment() { ++counter; }public:    _swap(){}    void operator ()(int& a, int& b){        int tmp = a;        a = b;        b = tmp;        inc();    }    int getNrCalls() {return count; }};

_swap swap;

int a = 3, b = 5;swap(a, b);

Page 12: особенности программирования на с++

шаблоны

Шаблонами классов называется семейство классов с одинаковым поведением

Шаблонами функций называют семейство функций с одинаковым поведением

template<class TYPE>void swap(TYPE& p1, TYPE& p2){    TYPE tmp = p1;    p1 = p2;    p2 = tmp;}

Понятие шаблона функции часто ассоциируется с понятием алгоритма

Page 13: особенности программирования на с++

Шаблоны: статический полиморфизм

int main(){    int i1 = 3, i2 = 5;    float f1 = 1.2, f2 = 2.3;    double d1 = 1.003, d2 = 10;    swap(i1, i2);    swap(f1, f2);    swap(d1, d2);    return 0;}

Одно и то же имя функции используется с различными типами данных. Данное свойство называется статическим полиморфизмом, потому что определение поведения функции выполняется на этапе компиляции программы.

Page 14: особенности программирования на с++

Шаблоны:специализация шаблонов

Для какого-то типа данных можно указать специальную версию шаблона.

template<>

void swap(int* a, int* b){

int tmp = *a;

*a = *b;

*b = tmp;

}

Если шаблон (его специализация) не используются в программе, то на этапе компиляции он(а) не включается в бинарный код!

Page 15: особенности программирования на с++

С++11: автоматические типы Ключевое слово

auto предписывает компилятору самому определить тип переменной

auto val = 5;

Page 16: особенности программирования на с++

С++11: инициализаторы

Появилась возможность инициализировать классы-контейнеры при помощи списков инициализаций.

class Array10{    int _val[10];public:    Array10(std::initializer_list<int> list);};

Array10 a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};

Page 17: особенности программирования на с++

С++11: лямбда-функции

лямбда-выражения позволяют программистам ускорить написание кода. Под лямбда-выражениями понимают специальный способ записи функторов.

[](int x, int y) { return x + y; } 

// то же, что и [](int x, int y) -> int{ int result = x + y; return result; }

struct sum{    int opertator()(int x, int y){ return x+y;}

};

Page 18: особенности программирования на с++

C++11: нулевой указатель Использование в

качестве нулевого указателя значения 0 в некоторых случаях приводило к опасному коду. Рекомендуется использовать ключевое слово nullptr

void test(int);

void test(char*);

int main(){

test(0); // ???

test(nullptr); // !!!

return true;

}

Page 19: особенности программирования на с++

С++11: цикл «для каждого»int a[5] =

{1, 2, 3, 4, 5};

for(auto& el: a){++el;}

for(auto el: a){std::cout << el << " ";}

В новом стандарте С++ предлагается новая форма записи цикла for: for( type element: collection){}

Page 20: особенности программирования на с++

Спасибо за внимание!