- •1.1. Что такое программа и как она выглядит?
- •1.2. Комментарии
- •1.3. Зарезервированные слова и типы данных
- •1.4. Объявление переменных
- •1.5. Операции и выражения
- •1.6. Ввод и вывод
- •1.7. Переменные и константы
- •1.8 Логические операторы
- •1.9. Управляющие операторы
- •1.10. Операторы циклов
- •1.11. Операторы перехода
- •2. Функции
- •2.1. Передача параметров
- •2.2. Библиотечные функции
- •2.3. Локальные и глобальные переменные
- •Объявления функций
- •Время жизни и область видимости программных объектов
- •Int local_var; /* по умолчанию auto */
- •2.4. Перегрузка
- •3. Массивы
- •4. Структуры
- •Int numberPeriod; //число переодов начисления процентов
- •Int page; //Количество страниц
- •Void print(); /*Внимание, записывается только прототип функции */
- •Int yearBorn; //год рождения
- •Int yearBorn; //год рождения
- •4.1. Демонстрационные программы
- •Int done;/*переменная, которая информирует о конце списка файлов */
- •6. Объединения
- •Info;//Обявление переменной типа объединение
- •Info;//Обявление переменной типа объединение
- •7. Объектно-ориентированное программирование
- •7.1. Классы и объекты
- •Демонстрационные программы
- •Результат работы программы
- •7.2. Конструкторы и деструкторы
- •Конструктор копирования
- •7.5. Наследование
- •7.3. Создание объектов и обращение к членам объекта
- •8. Абстрактные типы данных
- •9. Пространство имен
- •Void greeting();/*это пространство имен содержит функцию с тем же именем*/
- •Void big_greeting(); /*эта функция не попадает ни в одно из созданных подпространств,т.Е. Принадлежит пространству имен std */
- •//Определение функций
- •Void big_greeting() /* определение данной функции не принадлежит ни одному из созданных пространств имен, следовательно дальнейший код помещается в глобальное пространство имен */
- •10. Строки
- •4.3 Демонстрационные программы
- •4.10. Класс string
- •Класс AnsiString
- •Класс AnsiString
- •Класс Set
- •4.9. Перегрузка операторов
- •Использование "умных" указателей
- •4.8. Полиморфизм
- •Главное меню — компонент MainMenu
- •Диалоги
- •Файлы и потоки
- •Ввод-вывод в файл
- •Ifstream inStream; //Объявление входного потока
- •InStream.Open("character.Dat"); /*присоединение файла к входному потоку */
- •InStream.Close(); //закрытие входного потока
- •If(!out){ //при неудачной попытке
- •If(in.Fail()){ //поток не создан, то сообщение и выход
- •Управление потоком ввода-вывода
- •5.2. Ввод имен файлов
- •5.3. Манипуляторы
- •5. Указатели
- •5.1.Типы указателей и операции с указателями
- •Адресная арифметика
- •Сравнение указателей
- •Преобразование типа указателя
- •Указатель void
- •5.2. Динамические массивы
- •Int array[10]; //объявляется массив с именем array
- •Int a[10]; //объявляется массив с именем a
- •Int *array1; //указатель типа int с именем array1
- •Int *array[5];/*массив с именем array, его элементы указатели*/
- •Int (*point)[4][5]; /*объявление указателя на двумерный массив без имени */
- •Использование указателей в функциях и указатели на функции
- •Указатель классов
- •Шаблоны
- •Шаблоны функций
- •Void Swap (t& X, t& y) /* к моменту обращения тип т будет известен и заменен, например, на int */
- •Void sort(t array[], int maxIndex){ /*передали массив и его размер */
- •6.2. Шаблоны классов
- •6.3 Демонстрационные программы
- •7.1 Обработка исключений
- •Исключения и их стандартная обработка
- •Базовый класс исключений vcl Exception
- •Упражнения
- •Обработка исключительных ситуаций, возбуждаемых оператором new
- •Исходные файлы и объявление переменных
- •Связаные списки
- •Void newHead( //прототип функции создающей узел
- •Void newHead(//прототип функции создания узла
- •Поиск в связанных списках
- •Void newHead(PtrNode& head, //адрес головного узла
- •Директивы препроцессора.
- •Структура файла проекта
- •Структура make-файла
- •Структура модуля
- •Структура h-файла
- •Файл формы
- •Особенности программирования под Windows.
- •Функция WinMain
- •Создание проекта Win32Application.
- •Библиотека mfc.
- •Создаем код
- •Шпаргалка
- •Структура файла проекта
- •Структура make-файла
- •Структура модуля
- •Структура h-файла
- •Файл формы
- •Файл проекта
- •Введение
- •Свойства компонентов
- •События
- •Менеджер проектов
- •Пример: создание простейшего приложения
- •Графика Внедрение картинок
- •Редактор изображений
- •Классы для хранения графических объектов.
- •If (SelectDirectory( //Компонент библиотеки
- •Методы создания собственной графики. Рисование по пикселам
- •Int px, py; //координаты пикселей
- •Рисование с помощью пера
- •Int px, py; //координаты пикселей
- •Рисование кистью
- •Мультимедиа и анимация Общие сведения о звуковых и видеофайлах
- •Способы воспроизведения звуков
- •Создание мультфильма
- •Воспроизведение немых видео клипов — компонент Animate
- •Проигрыватель MediaPlayer
- •Процессы, потоки, распределенные приложения
- •If include "uOverlayl.H" // включение головного файла приложения
- •Функция CreateProcess
- •490 _ Глава 7
- •7.8.4 Элементы ActiveX
- •492 Глава 7
- •494 Глава 7
- •7.9 Компоненты-серверы сом
- •496 Глава 7
- •7.9.2 Свойства и методы сервера Word
- •500 Глава 7
- •Заключение
- •Что такое ansi?
- •Почему вместо русских букв в консольном приложении выводится мусор? Автор: Алексей Кирюшкин Версия текста: 1.0
- •Раздел I.2Выход 1
- •Раздел I.3Выход 2
- •Раздел I.4Выход 3
- •Раздел I.5Выход 4
- •(A)Потоки
- •(C)Ввод-вывод файлов
- •Выбор компонентов для групповых операций
- •Установка разделяемых свойств компонентов
- •Изменение размера компонентов
- •Выравнивание компонентов
- •Пример: Создание текстового редактора Проектирование формы приложения
- •Создание обработчиков событий
- •Создание меню
7.3. Создание объектов и обращение к членам объекта
В рассмотренных примерах мы уже создавали объекты классов и знаем, что после того как класс созан можно объявить один или несколько его объектов, т.е. экземпляров (переменных) данного класса. Процесс объявления ничем не отличается от объявления переменных базового типа, например если создан класс с именем MyClass, то объявление выглядит так:
MyClass object1, object2(x1), object3(x1,x2,x3);
Иначе говоря объявление объекта выглядиттак
Имя_класса имя_объекта(список_членов класса);
Членами класса могут быть данные, функции, классы, имена типов. Хотя мы в своих примерах будем использовать только базовые типы.
Из рассмотренных примеров уже стало ясно, что к членам объекта можно обращаться с помощью оператора точка. Еще раз подробнее рассмотрим этот вопрос. Предположим, что имеется класс MyClass, с соответствующим ему конструктором MyClass(описание аргументов), функцией MyFunction(x,y) и данными u,v. Тогда после создания объекта, который в данном случае объявляется как
MyClass MyObject(значение аргументов);
к функции можно обратиться так
MyObject. MyFunction(x,y),
а к переменным
MyObject.u; MyObject.v ;
Ниже приведен пример, в котором конструктор класса записывает числа от 0 до 9 в массив из 10 элементов. Функция print выводит на экран этот массив несколько раз. Количество обращений к этой функции зависит от числа rule, которое вводится из главной функции main. При создании объекта MyObject массив заполняется целыми числами и выводится на экран. После этого формируется новый массив и происходит обращение к функции print через MyObject.print .
#include<iostream>
using namespace std;
// Пример класса с именем MyClass
class MyClass{
public:
int m; /*Вспомогательная переменная необходимая для иллюстрации
работы программы */
void print(int intArray[10]);
MyClass(int rule);
};
void MyClass::print(int intArray[10]){ // Описание функции члена
for(int i=0;i<10;i++) cout<<intArray[i]<<",";
cout<<endl;
cout<<"m="<<m<<endl;
} //Здесь точка с запятой не ставятся, т.к. это функция
MyClass::MyClass(int rule){ // Описание конструктора
int array[10];
m=1;
cout<<"rule="<<rule<<endl;
for(int i=0;i<10;i++) array[i]=i;
for(int i=0;i<rule;i++) print(array);
} /*Здесь точка с запятой не ставятся хотя их присутствие
не вызовет ошибки, т.к. это будет пустой оператор */
//-----------------------------------------------------
#include <windows>
void main(){
SetConsoleOutputCP(1251); //Смена кодировки
int number, arr[10]={9,8,7,6,5,4,3,2,1,0}; //Инициализация массива
cout<<"Введите целое число"<<endl;
cin>>number;
MyClass MyObject(number);
cout<<”Число m и массив изменены”;
MyObject.m=10; // Изменяется вспомогательная переменная
MyObject.print(arr); // Выводится новый массив
}
Результат можно видеть на рисунке
Этот пример говорит о том, что оператор точка позволяет выполнить обращение к членам класса.
При работе с объектами можно использовать указатели. Для этого, сначала, нужно объявить указатель.
MyClass object1, object2, *pointerMyClacc;
где *pointerMyClacc – указатель на объект класса MyClacc.
Затем присвоить указателю адрес того объекта с которым предполагается дальнейшая работа.
pointerMyClacc=& object1;
К членам класса можно обращаться через указатель с помощью оператора -> следующим образом:
Указатель_класса->имя_члена_класса
Например, если MyClass имеет поля
int i,j,k;
double x,y,z;
то следующий код будет верен.
pointerMyClacc->i=1; pointerMyClacc->j=2;
pointerMyClacc->k= pointerMyClacc->i- pointerMyClacc->j;
pointerMyClacc->x=1.234; pointerMyClacc->y=0.567e-5;
pointerMyClacc->z= pointerMyClacc->x+ pointerMyClacc->y;
С помощью оператора -> можно бращаться к функции класса. Так если в MyClacc есть функция sum(x,y), то ее можно вызвать так:
pointerMyClacc->sum(x,y);
Код всей программы приведен ниже
//Пример применения указателей
class MyClass{
public:
int i,j,k;
int sum(int,int);
double x,y,z;
};
int MyClass::sum(int a,int b){
return a+b; return a+b;
}
//-------------------------------------
#include <iostream.h>
void main(){
MyClass mCL,*pointerMyClacc;
pointerMyClacc=&mCL;
pointerMyClacc->i=1; pointerMyClacc->j=2;
pointerMyClacc->k= pointerMyClacc->i- pointerMyClacc->j;
pointerMyClacc->x=1.234; pointerMyClacc->y=0.567e-5;
pointerMyClacc->z= pointerMyClacc->x+ pointerMyClacc->y;
cout<<pointerMyClacc->k<<endl;
cout<<pointerMyClacc->z<<endl;
int x,y;
cout<<"x=";
cin>>x;
cout<<"y=";
cin>>y;
cout<<"RESULTAT="<<pointerMyClacc->sum(x,y)<<endl;
}
Внимательного читателя фраза – “указатель класса” должна смутить. Действительно, о каких указателях может идти речь, если память выделяется объектам при их инициализации, а не самим классам. Конечно, это указатели на компоненты объектов. В данном случае название не совсем удачно.
Итак, к члену класса можно обращаться либо так:
имя_объекта.имя_члена класса
либо так:
указатель_на_объект_класса -> имя_члена класса
Но есть еще один способ – создать указатель члена класса не создавая указателя на объект. Продемонстрируем эту возможность на примере. Пусть имеется класс с именем с именем MyClass в котором есть переменная m типа int. В этом случае можно объявить указатель на переменную m.Пусть имя этого указателя будет point_m, а его объявление выглядит так:
int (MyClass::*point_m); /*Объявляется как обычный указатель, только после типа все записывается в скобках и кроме того добавляется имя класса */
Далее идет присвоение адреса
point_m=&MyClass::m; //Присвоение адреса
Разыменовывание переменной и присвоение значения:
MyObject.*point_m=100;
Этот способ не очень поятен, но еще более непонятно, по крайней мере на первый взгляд, выглядят операции с указателями для функций. Указатели на функции, принадлежащие классу (напомним, что они еще называются методами), имеют синтаксис:
Тип_возвращаемого_значения (имя_класса::*имя_указателя_на_метод) (спецификация параметров функции);
Хотя если внимательно посмотреть ничего сложного здесь нет. Это обычное объявление функции, только вместо ее имени в круглых скобках записывается соответствующий ей указатель. Например, если в классе MyClass есть функция print, то вне класса для этой функции можно объявить указатель
void (MyClass::*pointPrint)(int intArray[10]); /*Это объявление
указателя с именем pointPrint для функции */
после чего следует задать его значение
pointPrint=&MyClass::print; //присваивание адреса или настройка
Наконец вызвать функцию по указателю
(MyObject.*pointPrint)(arrZero);
Подобным образом можно выполнить указатель на данные.
Рассмотрим пример программы иллюстрирующий сказанное. В программе используется класс, содержащий одну переменную m и функцию print(int intArray[10]), которая имеет параметр в виде массива.
// Пример MyClass с указателями
#include<iostream>
using namespace std;
class MyClass{
public:
int m;
void print(int intArray[10]);
MyClass(int rule);
};
//------------Определение функции и конструктора--------
//функция print выводит на экран массив intArray и целое число m
void MyClass::print(int intArray[10]){
for(int i=0;i<10;i++) cout<<intArray[i]<<",";
cout<<endl;
cout<<"m="<<m<<endl;
}
/* конструктор, создает массив целых чисел от 0 до 9 включительно
и выводит на экран весь массив и число m заданное в переменной
rule количество раз */
MyClass::MyClass(int rule){
int i,array[10];
m=1;
cout<<"rule="<<rule<<endl;
for(i=0;i<10;i++) array[i]=i;
for(i=0;i<rule;i++) print(array);
};
//---------------Описание фунции main()-------------
void main(){
int number=5;
MyClass MyObject(number);
int arrZero[10]={0,0,0,0,0,0,0,0,0,0}; //Вспомогательный массив
//----- иллюстрация обращения к членам класса через указатель---
int (MyClass::*point_m); /*Объявление указателя класса MyClass
для членов типа int */
point_m=&MyClass::m; /*присвоение адреса переменной m*/
MyObject.*point_m=100; /*разыменовывание переменной m
и присвоение ей значения 100 */
//Обращение к функции через указатель
void (MyClass::*pointPrint)(int intArray[10]); /*объявление
указателя на функцию из класса MyClass с параметром в виде
массива из 10-ти элементов, которая возвращает тип int */
pointPrint=&MyClass::print; //инициализация указателя
(MyObject.*pointPrint)(arrZero); //вызов функции
}
Результат выполнения программы представлен на рисунке. После объявления объекта, на экран 5 раз выводится созданный конструктором массив целых чисел от 0 до 9 и число m, определенное в конструкторе. Функция main() заканчивается присвоением через указатель нового значения числу m и вызове на экран метода print с новым массивом.
Следует заметить, что указатель на компоненты класса можно также использовать в качестве фактического параметра при вызове функций, т.е. вместо параметра передавать адрес.
Приведенные примеры используют операцию разыменовывания указателей на компоненты класса. Хотя к членам объектов можно обратиться с помощью операции “->*” . Синтаксис здесь такой
Указатель_на_объект_класса->*указатель_на_данные
Указатель_на_объект_класса->*указатель_на_метод(параметры)
В качестве иллюстрации возьмем предыдущий пример и заменим в нем имя объекта на указатель класса.
// Пример MyClass – класс с указателями
#include<iostream>
using namespace std;
class MyClass{
public:
int m;
void print(int intArray[10]);
MyClass(int rule);
};
//------------Определение функции и конструктора--------
//функция print выводит на экран массив intArray и целое число m
void MyClass::print(int intArray[10]){
for(int i=0;i<10;i++) cout<<intArray[i]<<",";
cout<<endl;
cout<<"m="<<m<<endl;
}
/* конструктор, создает массив целых чисел от 0 до 9 включительно
и выводит на экран весь массив и число m заданное в переменной
rule количество раз */
MyClass::MyClass(int rule){
int i,array[10];
m=1;
cout<<"rule="<<rule<<endl;
for(i=0;i<10;i++) array[i]=i;
for(i=0;i<rule;i++) print(array);
};
//---------------Описание фунции main()-------------
void main(){
int number=5;
MyClass MyObject(number),*pointMO; //объявление указателя класса
pointMO=&MyObject;
int arrZero[10]={0,0,0,0,0,0,0,0,0,0}; //Вспомогательный массив
//----- иллюстрация обращения к членам класса через указатель---
int (MyClass::*point_m);
для членов типа int */
point_m=&MyClass::m;
pointMO->*point_m=100; /*применение двух указателей для присвоения значения переменной класса */ и присвоение ей значения 100 */
//Обращение к функции через указатель класса и указатель функции
void (MyClass::*pointPrint)(int intArray[10]); /*объявление
указателя на функцию из класса MyClass с параметром в виде
массива из 10-ти элементов, которая возвращает тип int */
pointPrint=&MyClass::print;
(pointMO->*pointPrint)(arrZero); /*обращение к функции через два
указателя */
}
Результат этой программы точно такой как и предыдущей.
При работе с классами используется один необычный указатель c фиксированным именем this. Обычно он используется тогда, когда нужно разделить переменные класса и параметры функции с одинаковыми именами. Например:
#include<iostream>
using namespace std;
class summa{
int x,y; //переменные класса
public:
summa(int x, int y);
};
summa::summa(int x, int y){
this->x=1;this->y=2; //инициализация переменных класса
cout<<"thisx="<<this->x<<endl;
cout<<"thisy="<<this->y<<endl;
cout<<"this->x+this->y="<<this->x+this->y<<endl;
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
cout<<"x+y="<<x+y<<endl;
}
void main(){
int a=3,b=4;
summa sum(a,b);
}
Вообще указатель this автоматически передается любой функции-члену при её вызове и указывает на объект генериоующий вызов. Например:
object.fun1(); /* предполагается, что object
* это имя объекта*/
Функции fun1()автоматически передается указатель на объект object. Этот указатель и называется this. Указатель this автоматически передается только функциям-членам.
Рассмотрим предварительный пример в котором пока нет указателя this. В коде класса приведенного ниже используется функция strcpy (string copy) из библиотеки string. Функция strcpy
// Демонстрация указателя this
#include <iostream>
#include <string>
using namespace std;
class inventory { //класс называется опись
char item[20]; // item в переводе означает пункт, статья, позиция
double cost; // cost в переводе - цена
int on_hand;
public:
/*далее идет объявление конструктора, котоый в дальнейшем
не описан, т.к. все что он делает определено в его объявлении */
inventory(char *i, double c, int o) {
strcpy(item, i);
cost = c;
on_hand = o;
}
void show(); //функция, осуществляющая вывод
};
void inventory::show()
{
cout << item; //вывод на экрае всего массива
cout << ": $" << cost;
cout << " On hand: " << on_hand << "\n";
}
int main()
{
inventory object("wrench", 4.95, 4);
object.show();
return 0;
}