Язык С++ допускает так называемое сложное наследование, то есть одновременное наследование от двух и более базовых классов.
class naslednik: public B1, public B2, protected B3 {........};
При этом в иерархии классов может оказаться так, что класс косвенно унаследует несколько представителей одного и того же базового класса (например, и B1 и B2 являются наследниками одного и того же класса А). Чтобы избежать такой ситуации при создании представителей класса-наследника применяют операцию разрешения видимости.
class A { protected: int mama;
int papa;
......}; void main() {
naslednik sinok; sinok.B1::mama=8; sinok.B2::papa=89;
........}
Тема 44. Виртуальные функции.
Среди особенностей объектно-ориентированного программирования особо выделяют полиморфизм - способность объектов различных классов отвечать на запрос той ли иной функции сообразно типу своего класса. Для обеспечения полиморфизма С++ предлагает механизм виртуальных функций.
Рассмотрим пример:
# include <iostream.h> class X
{ public:
double tryp (float x) {return 5*x;} double giena (float x) {return 2+A(x);}
};
class Y : public X { public:
double tryp (float x) {return 5*10*x;}
};
void main() { Y proval;
cout << proval.giena(2)<<endl;
}
В этой программе выражение proval.giena(2) приведет к вызову наследуемой функции X::giena, которая, в свою очередь, вызовет X::tryp, а не Y::tryp. Таким образом, полиморфной реакции класса
Программирование на языке высокого уровня 09.03.01 |
51 |
не наблюдается. Если же добавить ключевое слово virtual перед именем функции tryp как при описании класса X, так и при описании класса Y, то требуемый эффект будет достигнут, то есть при работе программы будет вызвана замещающая функция Y::tryp.
После того, как функция будет объявлена виртуальной, ее можно переопределить (заместить) только в классах-потомках. Замещающие функции должны иметь тот же список параметров. При этом виртуальные функции могут замещать невиртуальные функции базовых классов. Очень важно, что при объявлении в некотором классе функции виртуальной, в классах-потомках, переопределяющих эту функцию, она также будет виртуальной, но только если она имеет тот же список параметров. Если же переопределенная функция в классе-потомке имеет другой список параметров, то ее версия из базового класса будет недоступна классу-потомку и всем его потомкам.
Виртуальная функция-элемент некоторого класса может быть объявлена чистой:
virtual тип имя(аргументы)=0;
Такие функции создаются в базовом классе затем, чтобы потом переопределяться в классах, производных от него. Класс, объявляющий одну или несколько чисто виртуальных функций, является абстрактным базовым классом. У такого класса нельзя создать представитель, а нужен он только в качестве базового для дальнейшего порождения классов, которые будут реализовывать его чисто виртуальные функции. Существует возможность объявлять ссылки или указатели на абстрактный класс.
Введение в С++ механизма абстрактных базовых классов позволяет делать более четкой организацию иерархии классов.
Тема 45. Статические элементы класса. Пространства имен.
Можно объявить элемент класса (как данные, так и функции) статическим. Статический элемент данных существует только один, вне зависимости от того сколько представителей класса создано в процессе работы программы. Обратиться к открытому статическому элементу класса можно через любой представитель класса при помощи операций прямого или косвенного доступа либо с помощью операции разрешения видимости с использованием имени класса. Помимо объявления в определении класса, статический элемент должен еще и определяться:
class giena {
public: static int i;
......
};
Программирование на языке высокого уровня 09.03.01 |
52 |
int giena::i=0;
Если статический элемент закрытый, то для доступа к нему в составе класса предусматривается открытая статическая функцияэлемент. Такая функция может вызываться даже если не существует никаких представителей класса. Статическая функция-элемент может обращаться только к статическим элементам данных класса и вызывать только другие статические функции-элементы класса.
Язык С++ позволяет разрешать конфликты между разными переменными с одинаковыми именами, которые происходят из-за участия в разработке проектов большого числа программистов. Речь идет именно о глобальных переменных, так как конфликты между локальными и глобальными переменными всегда разрешаются в пользу локальных.
Проект можно разбить на части, определив для этих частей различные пространства имен. Для определения пространства имен используется следующий синтаксис:
namespace ИМЯ { список переменных}.
Для явного обращения к такой переменной используется префикс с названием соответствующего пространства имен и операцией разрешения видимости. Допускается использование вложенных пространств имен:
namespace TTT { int t;
namespace TTT1 { int t;
}
}.
Пример обращения - TTT::TTT1::x=99;
Для доступа к элементам конкретного пространства имен можно явно обращаться к ним с использованием соответствующей приставки либо использовать конструкцию using в двух различных формах.
Если элемент некоторого пространства имен объявляется при помощи ключевого слова using, то все ссылки на этот элемент (имя переменной, массива, функции и т.д.) без каких-либо приставок будут соотносится с пространством имен, указанным в объявлении.
namespace AAA {
int fun (int i) {return i;}
}
namespace BBB {
int fun (int i) {return i*i;}
}
void main(void) { using BBB::fun; int x=7,y;
Программирование на языке высокого уровня 09.03.01 |
53 |
y=fun(x);
printf("%d\n",y);
}
Вторая форма использования ключевого слова using имеет вид: using namespace ИМЯ_ПРОСТРАНСТВА_ИМЕН;
В этом случае указанное пространство имен будет приниматься по умолчанию (без указания префиксов), если не используются локальные переменные с совпадающими именами.
# include <stdio.h> namespace A1 {
int x=11; int y=111; int w=1111;
}
namespace A2 {
int x=22; int y=222; int z=2222;
}
void main(void) {
using namespace A1; using namespace A2; using A2::x;
int z=3333; printf("x=%d,y=%d,z=%d,w=%d",x,A1::y,::z,w); printf("\nz=%d\n",z);
}
Будет напечатано x=22,y=111,z=2222,w=1111 z=3333.
Несмотря на то, что в программе указаны сразу два пространства имен, ошибок компилятора не возникает. Но при попытке обратиться к переменной y не используя явных приставок, будет выдано сообщение об ошибке.
Использование пространств имен внутри функций допустимо синтаксически, но лишено смысла.
Программирование на языке высокого уровня 09.03.01 |
54 |
Раздел 7. Визуальное программирование с использованием языка С++. Лекции 35-37.
Темы 46-48. Визуальное программирование с использованием языка С++ в среде С++ Builder (Turbo C++ 2006).
C++ Builder включает в свой состав визуальную интегрированную среду разработки, которая позволяет создавать достаточно сложные программы, работающие под управлением операционной системы Windows, и при этом минимизировать объем текста, который приходится писать программисту. При этом существует возможность редактирования ресурсов, входящих в приложение, как в визуальном, так и в текстовом представлении, причем оба эти представления изменяются синхронно.
Основой приложений, создаваемых в среде C++ Builder, являются формы. Создание пользовательского интерфейса приложения заключается в добавлении в окно формы элементов - объектов C++ Builder, называемых компонентами, и в установке значений их свойств. Кроме этого пишется текст специальных программ - обработчиков событий, на которые тем или иным образом реагируют размещенные в форме компоненты.
Формы и модули, входящие в приложения, управляются файлами проекта. Файл проекта имеет расширение brp, а кроме него создается файл исходного текста проекта с таким же именем, но с расширением cpp. Как правило, изменения в этот файл вносятся автоматически.
При добавлении к проекту формы создаются файл ресурсов формы
срасширением dfm, содержащий информацию об интерфейсных элементах и других компонентах, принадлежащих форме, файл модуля
срасширением cpp, в котором, в частности, содержится текст обработчиков, а также файл с расширением h, в котором содержится описанием классов формы, а также пользовательских классов.
Для изменения свойств компонентов во время проектирования служит инспектор объектов. При помощи инспектора объекта можно
также сгенерировать прототип обработчика того или иного события и создать текст программы, описывающей действия, которые должны выполниться, если это событие произойдет.
При внесении в форму новых компонентов или генерации новых обработчиков событий соответствующие описания автоматически добавляются в h-файл. При удалении из формы компонентов их описания удаляются из h-файла, а описания обработчиков событий сохраняются. При переименовании компонентов изменяются их описания в h-файле, а также имена и описания обработчиков
Программирование на языке высокого уровня 09.03.01 |
55 |