Форум программистов, компьютерный форум CyberForum.ru

Mayers S. vs C++11 standard - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Численное дифф-ние многочленом третьей степени http://www.cyberforum.ru/cpp-beginners/thread812479.html
Было дано задание реализовать Численное дифференцирование с помощью многочлена третьей степени на C++. Я, кажется, смогла понять общий принцип, но на стадии реализации приключился ступор. http://i1.imageban.ru/thumbs/2013.03.19/48072c724b3519d52dba73f5d3fa4379.jpg http://i3.imageban.ru/thumbs/2013.03.19/9a79e8834e7702218e61273f3d3a462c.jpg Как я поняла, нужно преобразовать формулу, ведь...
C++ Вращение окружностей вокруг определенного центра Всем доброго времени и суток! Как сделать вращающиеся окружности вокруг центра? Рисунок есть. Не могу понять как задать цикл вращения... Версия 4.9.9.2 Dev-C++#include<conio.h> #include<graphics.h> main() { http://www.cyberforum.ru/cpp-beginners/thread812476.html
из L- ой строки вычесть K- ую умноженную на a(LK)/a(KK) C++
помогите пожалуйста написать программу."заданы матрица А размером 4*4 и числа K и L (K!=L;1<=K;L<4).из L строки вычесть K умноженную на a(LK)/a(KK) ."в с++ Borland
C++ Массив: Переместить в массив Y все числа, дробная часть которых больше 5.
Помогите решить, вообще не понимаю как в С++ с дробной частью работать. Задан массив X(N) дробных чисел. Переместить в массив Y все числа, дробная часть которых больше 5. Вывести на экран абсолютные значения чисел, исходного массива X и значения массива Y после выполнения операций над ним.
C++ С++ Массив указателей, выполнить сортировку по алфавиту http://www.cyberforum.ru/cpp-beginners/thread812435.html
Подготовьте массив указателей на NOTE на 50 элементов. Считайте все записи из файла "3.dat" . Для чтения каждой отдельной записи осуществите динамический захват памяти. Соответствующий адрес храните в массиве указателей. Выполните сортировку данных по алфавиту (по пункту назначения) - причем сортировать потребуется только указатели в массиве.
C++ Сортировка Доброе утро Надо написать программу сортировки числовой последовательность типа 8, 4, 1, 9, 2, 1, 7, 4 посредством выбора. Отображайте состояние списка после каждого прохода. Предусмотреть сортировку символьной последовательности типа V, В, L, А, Z,Y,C,H,S,S,B,H. подробнее

Показать сообщение отдельно
ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410

Mayers S. vs C++11 standard - C++

19.03.2013, 10:20. Просмотров 396. Ответов 4
Метки (Все метки)

Привет, ребят!

У Майерса читал: для предоставления виртуальной функции реализации по умолчанию, которой нужно пользоваться по явному требованию наследующего и переопределяющего виртуальную функцию программиста, т.е. чтобы не получилось так, что в наследном классе забыл её переопределить и будет срабатывать реализация из базового класса (а так же с целью незагромождения пространства имен класса функцией defaultImplementation, которую можно было бы использовать для реализации этой идеи, например), используется определение чисто виртуальной функции. Короче, вот выжимка из книги:

Кликните здесь для просмотра всего текста
Оказывается, иногда может быть опасно использовать обычные виртуальные функции, которые обеспечивают как интерфейс функции, так и ее реализацию по умолчанию. Для того чтобы понять, почему имеется такая вероятность, рассмотрим иерархию самолетов в компании XYZ Airlines. XYZ располагает самолетами только двух типов: модель A и модель B, и оба летают одинаково. В связи с этим разработчики XYZ проектирует такую иерархию:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 class Airport {}; // представляет аэропорты
    class Airplane {
    public:
    virtual void fly(const Airport& destination);
    ...
    };
    void Airplane::fly(const Airport& destination)
    {
    код по умолчанию, описывающий полет самолета
 
    в заданный пункт назначения – destination
    }
    class ModelA: public Airplane {...};
    class ModelB: public Airplane {...};
Чтобы выразить тот факт, что все самолеты должны поддерживать функцию fly, и для того чтобы засвидетельствовать, что для разных моделей, в принципе, могут потребоваться различные реализации fly, функция Airplane::fly объявлена виртуальной. При этом во избежание написания идентичного кода в классах ModelA и ModelB в качестве стандартного поведения используется тело функции Airplane::fly, которую наследуют как ModelA, так и ModelB.
Это классический пример объектно-ориентированного проектирования. Два класса имеют общее свойство (способ реализации fly), поэтому оно реализуется в базовом классе и наследуется обоими подклассами. Благодаря этому проект явным образом выделяет общие свойства, что позволяет избежать дублирования, благоприятствует проведению будущих модернизаций и упрощает долгосрочную эксплуатацию – иными словами, обеспечивает все, за что так ценится объектно-ориентированная технология. Программисты компании XYZ Airlines могут собой гордиться.
А теперь предположим, что дела XYZ идут в гору, и компания решает приобрести новый самолет модели C. Эта модель отличается от моделей A и B, в частности, тем, что летает по-другому.
Программисты компании XYZ добавляют в иерархию класс ModelC, но в спешке забывают переопределить функцию fly:

C++
1
2
3
 class ModelB: public Airplane {
    ... // функция fly не объявлена
    };
В своем коде потом они пишут что-то вроде этого:

C++
1
2
3
4
Airport PDX(...); // PDX – аэропорт возле моего дома
    Airplane *pa = new ModelC;
    ...
    pa->fly(PDX); // вызывается Airplane::fly!
Назревает катастрофа: делается попытка отправить в полет объект ModelC, как если бы он принадлежал одному из классов ModelA или ModelB. Такой образ действия вряд ли может внушить доверие пассажирам.
Проблема здесь заключается не в том, что Airplane::fly ведет себя определенным образом по умолчанию, а в том, что такое наследование допускает неявное применение этой функции для ModelC. К счастью, легко можно предложить подклассам поведение по умолчанию, но не предоставлять его, если они сами об этом не попросят. Трюк состоит в том, чтобы разделить интерфейс виртуальной функции и ее реализацию по умолчанию. Вот один из способов добиться этого:

C++
1
2
3
4
5
6
7
8
9
10
11
 class Airplane {
    public:
    virtual void fly(const Airport& destination) = 0;
    ...
    protected:
    void defaultFly(const Airport& destination);
    };
    void Airplane::defaultFly(const Airport& destination)
    {
    код по умолчанию, описывающий полет самолета в заданный пункт назначения
    }
Обратите внимание, что функция Airplane::fly преобразовна в чисто виртуальную. Она предоставляет интерфейс для полета. В классе Airplane присутствует и реализация по умолчанию, но теперь она представлена в форме независимой функции defaultFly. Классы, подобные ModelA и ModelB, которые хотят использовать поведение по умолчанию, просто выполняют встроенный вызов defaultFly внутри fly (см. также правило 30 о взаимодействии встраивания и виртуальных функций):

C++
1
2
3
4
5
6
7
8
9
10
11
12
class ModelA: public Airplane {
    public:
    virtual void fly(const Airport& destination)
    { defaultFly(destination};}
    ...
    };
    class ModelB: public Airplane {
    public:
    virtual void fly(const Airport& destination)
    { defaultFly(destination};}
    ...
    };
Теперь для класса ModelC возможность случайно унаследовать некорректную реализацию fly исключена, поскольку чисто виртуальная функция в Airplane вынуждает ModelC создавать свою собственную версию fly.

C++
1
2
3
4
5
6
7
8
9
class ModelC: public Airplane {
    public:
    virtual void fly(const Airport& destination)
    ...
    };
    void ModelC::fly(const Airport& destination)
    {
    код, описывающий полет самолета ModelC в заданный пункт назначения
    }
Эта схема не обеспечивает "защиту от дурака" (программисты все же могут создать себе проблемы копированием/вставкой), но она более надежна, чем исходная. Что же касается функции Airplane::defaultFly, то она объявлена защищенной, поскольку действительно является деталью реализации класса Airplane и производных от него. Пассажиры теперь должны беспокоиться только о том, чтобы улететь, а не о том, как происходит полет.
Важно также то, что Airplane::defaultFly объявлена как невиртуальная функция. Это связано с тем, что никакой подкласс не должен ее переопределять – обстоятельство, которому посвящено правило 36. Если бы defaultFly была виртуальной, перед вами снова встала бы та же самая проблема: что, если некоторые подклассы забудут переопределить defaultFly должным образом?
Иногда высказываются возражения против идеи разделения функций на обеспечивающие интерфейс и реализацию по умолчанию, такие, например, как fly и defaultFly. Прежде всего, отмечают противники этой идеи, это засоряет пространство имен класса близкими названиями функций. Все же они соглашаются с тем, что интерфейс и реализация по умолчанию должны быть разделены. Как разрешить кажущееся противоречие? Для этого используется тот факт, что производные классы должны переопределять чисто виртуальные функции и при необходимости предоставлять свои собственные реализации. Вот как можно было бы использовать возможность определения чисто виртуальных функций в иерархии Airplane:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Airplane {
    public:
    virtual void fly(const Airport& destination) = 0;
    ...
    };
    void Airplane::fly(const Airport& destination) // реализация чисто
    { // виртуальной функции
    код по умолчанию, описывающий полет
    самолета в заданный пункт назначения
    }
    class ModelA: pubic Airplane {
    public:
    virtual void fly(const Airport& destination)
    { Airplane::fly(destination);}
    ...
    };
    class ModelB: pubic Airplane {
    public:
    virtual void fly(const Airport& destination)
    { Airplane::fly(destination);}
    ...
    };
    class ModelC: pubic Airplane {
    public:
    virtual void fly(const Airport& destination);
    ...
    };
    void ModelC::fly(const Airport& destination)
    {
    код, описывающий полет самолета ModelC в заданный пункт назначения
    }
Это практически такой же подход, как и прежде, за исключением того, что тело чисто виртуальной функции Airplane::fly заменяет собой независимую функцию Airplane::defaultFly. По существу, fly разбита на две основные составляющие. Объявление задает интерфейс (который должен быть использован в производных классах), а определение задает поведение по умолчанию (которое может использоваться производным классом, но только по явному требованию). Однако, производя слияние fly и defaultFly, мы теряем возможность задать для этих функций разные уровни доступа: код, который должен быть защищенным (функция defaultFly), становится открытым (потому что теперь он находится внутри fly).


Сегодня нахожу кусочек стандарта:
[ Note: a function declaration cannot provide both a pure-specifier and a definition —end
note ] [ Example:
C++
1
2
3
struct C {
virtual void f() = 0 { }; // ill-formed
};
—end example ]

Майерс пишет примеры, которые соответствуют стандартному переносимому C++, в иных случаях - оговаривает обратное.

Я в недоумении.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru