Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
37. Что такое классы и объекты ? Что такое инкапсуляция ? Как определять новый класс и создать объекты этого класса ?
Вероятно, одним из наиболее важных понятий С++ является класс. Класс это объединение данных и функций. Функции предназначены для работы с данными.
Объявление класса myclass не задает ни одного объекта типа myclass, оно определяет только тип объекта, который будет создан при его фактическом объявлении. Чтобы создать объект, используйте имя класса, как спецификатор типа данных. Например, в этой строке объявляются два объекта типа myclass:
myclass ob1, ob2; // это объекты типа myclass
После того как объект класса создан, можно обращаться к открытым членам класса, используя оператор точка (.), аналогично тому, как осуществляется доступ к членам структуры. Предположим, что ранее объекты были объявлены, тогда следующие инструкции вызывают set_a() для объектов оb1 и оb2:
ob1.set_a(10); // установка версии а объекта оb1 равной 10 ob2.set_a(99); // установка версии а объекта оb2 равной 99
Как видно из комментариев, эти инструкции устанавливают значение переменной а объекта оb1 равной 10 и значение переменной а объекта оb2 равной 99. Каждый объект содержит собственную копию всех данных, объявленных в классе. Это значит, что а в оb1 отлично от а в оb2.
38. Открытые и закрытые члены класса . Как передавать и возвращать значения закрытых переменных ?
Функции и переменные, объявленные внутри объявления класса, называют членами (members) этого класса. По умолчанию все функции и переменные, объявленные в классе, становятся закрытыми для класса. Это означает, что они доступны только для других членов того же класса. Для объявления открытых членов класса используется ключевое слово public, за которым следует двоеточие. Все функции и переменные, объявленные после слова public, доступны как для других членов класса, так и для любой другой части программы, в которой находится этот класс.
Ниже приводится простое объявление класса:
class myclass
{
private:
int а;
public:
void set_a (int num);
int get_a () ;
};
Этот класс имеет одну закрытую переменную а, и две открытые функции, set_a() и get_a(). Обратите внимание, что прототипы функций объявляются внутри класса. Функции, которые объявляются внутри класса, называются функциями-членами (member functions).
Отметим, что и set_a() и get_a() имеют доступ к переменной а, которая для myclass является закрытой. Как уже говорилось, поскольку seta() и get_a() являются членами myclass, они могут напрямую оперировать с его закрытыми данными.
При определении функции-члена пользуйтесь следующей основной формой:
Тип_возвращаемого_значения имя_класса::имя_функции(список_параметров)
{
...// тело функции
}
Здесь имя_класса это имя того класса, которому принадлежит определяемая функция.
39. Как осуществляется реализация методов вне класса ? Встраиваемая реализация функций членов класса .
Этот класс имеет одну закрытую переменную а, и две открытые функции, set_a() и get_a(). Обратите внимание, что прототипы функций объявляются внутри класса. Функции, которые объявляются внутри класса, называются функциями-членами (member functions).
Поскольку а является закрытой переменной класса, она недоступна для любой функции вне myclass. Однако поскольку set__a() и get_a() являются членами myclass, они имеют доступ к а. Более того, set_a() и get_a(), являясь открытыми членами myclass, могут вызываться из любой части программы, использующей myclass.
Хотя функции set_a() и get_a() и объявлены в myclass, они еще не определены. Для определения функции-члена вы должны связать имя класса, частью которого является функция-член, с именем функции. Это достигается путем написания имени функции вслед за именем класса с двумя двоеточиями. Два двоеточия называются оператором расширения области видимости (scope resolution operator). Например, далее показан способ определения функций-членов set_a() и get__a():
void myclass::set_a(int num)
{
a=num;
}
int myclass::get_a()
{
return a;
}
Отметим, что и set_a() и get_a() имеют доступ к переменной а, которая для myclass является закрытой. Как уже говорилось, поскольку seta() и get_a() являются членами myclass, они могут напрямую оперировать с его закрытыми данными.
40. Что такое конструкторы и деструкторы класса ? Для чего они используются ? Какова реализация конструкторов и деструкторов ?
Для инициализации объекта в С++ имеется функция-конструктор (constructor function), включаемая в описание класса. Конструктор класса вызывается всякий раз при создании объекта этого класса. Таким образом, любая необходимая объекту инициализация при наличии конструктора выполняется автоматически.
Конструктор имеет то же имя, что и класс, частью которого он является, и не имеет возвращаемого значения.
Функцией, обратной конструктору, является деструктор (destructor). Эта функция вызывается при удалении объекта. Обычно при работе с объектом в момент его удаления должны выполняться некоторые действия. Например, при создании объекта для него выделяется память, которую необходимо освободить при его удалении. Имя деструктора совпадает с именем класса, но с символом ~ (тильда) в начале.
Деструктор класса вызывается при удалении объекта
41.Что такое перегрузка конструкторов ?
42. Как создаются массивы объектов ? Каким образом инициализируется массивы объектов ?
43. Что такое наследование ? Каким образом указывается что данный класс является производным от базового класса ?
Наследование это средство, позволяющее одному классу наследовать характеристики другого. Согласно языку С++, наследуемый класс называется базовым классом. Класс, который наследует от базового, называется производным классом. Производный класс наследует все члены, определенные в базовом классе, и добавляет к ним свои собственные специфические элементы.
В С++ наследование реализуется путем включения одного класса (базового) в объявление другого (производного). Другими словами, в объявлении производного класса указывается, какой класс является для него базовым.
Общая форма наследования приведена ниже:
class производный-класс : сп_доступа базовый-класс {
тело производного класса
}
44. Если базовый класс исследуется как закрытый , как при этом осуществляется доступ к открытым членам базового класса ?
Здесь сп_доступа одно из ключевых слов public, private или protected. Если член класса объявлен как public, к нему можно обратиться из любого места в программе. Если член объявлен как private, он доступен только членам своего класса. При этом производные классы не имеют доступа к членам private базового класса. Если член объявлен как protected, он доступен только членам своего класса и производных классов. Таким образом, атрибут protected позволяет члену наследоваться, но оставаться закрытым внутри иерархии классов.
Если базовый класс наследуется с атрибутом public, его открытые члены становятся открытыми членами производного класса, а его защищенные члены становятся защищенными членами производного класса. Если базовый класс наследуется с атрибутом protected, его открытые и защищенные члены становятся защищенными членами производного класса. Если базовый класс наследуется с атрибутом private, его открытые и защищенные члены становятся закрытыми членами производного класса Во всех случаях закрытые члены базового класса остаются закрытыми в этом классе.
45. Как можно сделать член доступным внутри иерархии но закрытым любом другом месте
Как вы уже знаете, члены класса часто объявляются закрытыми, чтобы предотвратить неавторизованный доступ или неразумное использование. Наследование от класса не нарушает ограничение доступа к закрытым членам. Таким образом, хотя производный класс включает все члены базового, он не может обратиться к закрытым членам базового класса. Например, если переменные width и height объявить в классе TwoDShape закрытыми, как это показано ниже, тогда Triangle не будет иметь к ним доступа.
/* Производным классам закрыт доступ к закрытым членам базового класса. */
class TwoDShape {
double width;
double height;
public:
void showDim () {
cout << "Ширина и высота составляют " <<
width << " и " << height << "\n";
}
};
// Triangle является производным от TwoDShape.
class Triangle : public TwoDShape {
public:
char style [20] ;
double area () {
//К закрытым членам базового класса обращаться нельзя
return width * height /2; // Ошибка! Доступ закрыт.
}
void showStyle () {
cout << "Треугольник " << style << "\n";
}
};
46. Передача объектов функции .
Передача в функции указателей
Для того, чтобы передать указатель в качестве аргумента, вы должны объявить параметр типа указателя. Вот пример:
// Передача функции указателя.
#include <iostream>
using namespace std;
//f() принимает указатель int * в качестве параметра.
void f (int *j); // f() объявляет параметр-указатель
int main () {
int i;
int *p;
p = &i; // p теперь указывает на i
f(p); // передача указателя
cout << i; // i теперь равно 100
return 0 ;
}
// f() получает указатель на int.
void f (int * j )
{
*j = 100; /* переменной, на которую указывает j,
теперь присвоено значение 100 */
}
47. Возвращение объектов функции . Функция может вернуть значение в вызывающий ее код. Возвращаемое значение представляет собой способ получить информацию из функции. Для возврата значения следует использовать второй вариант предложения return:
return значение;
Здесь значение это то значение, которое возвращается функцией в вызывающий ее код. Эта форма предложения return может использоваться только с функциями, не возвращающими void. Функция, возвращающая значение, должна задать тип этого значения. Тип возврата должен быть совместим с типом данного, используемого в предложении return. Если это не так, во время компиляции будет зафиксирована ошибка. Для иллюстрации работы с функциями, возвращающими значения, перепишем функцию bох() так, как это показано ниже. В этом варианте bох() возвращает вычисленный объем. Обратите внимание на то, что помещение функции с правой стороны знака равенства присваивает возвращаемое значение переменной.
// Возврат значения.
#include <iostream>
using namespace std;
int box(int length, int width, int height); // вернем объем
int main()
{
int answer;
answer = box(10, 11, 3); // присвоим возвращаемое значение
cout << "Объем равен " << answer;
return 0;
}
// Эта функция возвращает значение.
int box(int length, int width, int height)
{
return length * width * height ;//Вернем объем.
}
Вот вывод программы: Объем равен 330
48. Указатели на объекты . Массивы объектов . В С++ имеется тесная взаимосвязь между указателями и массивами. Во многих случаях указатель и массив являются взаимозаменямыми понятиями. Рассмотрим следующий фрагмент:
char str[80];
char *pl;
p1 = str;
Здесь str представляет собой массив из 80 символов, a p1 - указатель на символы. Однако для нас более интересна третья строка. В ней p1 присваивается адрес первого элемента массива str. (После присваивания p1 будет указывать на str[0].) И вот почему: в С++ использование имени массива без индекса образует указатель на первый элемент массива. Таким образом, операция
p1 = str;
присваивает указателю p1 адрес элемента str[0]. Это очень важный момент: при использовании в выражении неиндексированного имени массива образуется указатель на первый элемент массива.
49. Что такое множественное наследование ? Виды множественного наследование . В каком порядке вызываются конструкторы и деструкторы в иерархии классов ?
Класс может быть производным не только от одного базового класса , а и от многих . Этот случай называется множественным наследованием .
Поскольку и базовый класс, и производный класс могут содержать конструкторы и деструкторы, важно понимать, в каком порядке они выполняются. Конкретно, в каком порядке вызываются конструкторы, когда начинает существовать объект производного класса? А когда объект перестает существовать, в каком порядке вызываются деструкторы? Для того, чтобы ответить на эти вопросы, начнем с такой простой программы:
// Демонстация порядка выполнения работы конструкторов и леструкторов
//при наследовании
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class B{
public:
B() { cout << "Constructor of base clacc \n"; }
~B ( ) { cout << "Destructor of base clacc \n"; }
};
class D: public B {
public:
D() { cout << "Constructor of derived clacc \n"; }
~D () { cout << "Destructor of derived clacc \n"; }
};
int main () {
{ D ob;
// не делаем ничего, только конструируем и уничтожаем ob}
} _getch();
return 0;
}
50. Как создаются множественные наследование из нескольких базовых классов ? Что такое виртуальный базовый класс?
В С++ имеется возможность создать производный класс, который будет наследовать одновременно от двух или нескольких базовых классов. Например, в этой короткой программе класс D наследует и от В1, и от В2:
// Пример нескольких базовых классов.
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class Bl {
protected:
int x;
public:
void showx () { cout << x << "\n"; }
};
class B2 {
protected:
int y;
public:
void showy () { cout << y << "\n"; }
};
// Здесь D одновременно наследует и от В1, и от B2.
class D: public Bl, public B2 {
public:
/* х и у доступны, потому что они объявлены
в В1 и В2 защищенными, а не закрытыми. */
void set(int i, int j) { x = i; y = j; }
};
int main ( ) {
D ob;
ob. set (10 , 20); // берется из D
ob.showx() ; // из Bl
ob .showy() ; // из B2
_getch();
return 0;
}
Прежде чем расстаться с темной виртуальных элементов программирования нам следует коснутся вопроса виртуальных базовых классов , так как они имеют отношение к множественному наследованию .
51. Что такое полиморфизм ? Что такое виртуальная функция ? Как объявляется виртуальная функция в базовом и производных классах ?
Класс, который содержит виртуальные функции, называется полиморфным классом. Этот термин также относится и к классу, который наследует от базового класса, содержащего виртуальную функцию.
Виртуальной называется функция, объявленная в базовом классе с описателем virtual и переопределенная в одном или нескольких производных классах. Таким образом, каждый производный класс может иметь собственный вариант виртуальной функции. Свойства виртуальности проявляются у виртуальных функций, когда для их вызова используется указатель базового класса. Если виртуальная функция вызывается посредством указателя базового класса, С++ определяет, какой из вариантов этой виртуальной функции вызвать, основываясь на типе объекта, на который указывает указатель. Следовательно, если базовый класс содержит виртуальную функцию, и два или больше различных классов наследуют от этого базового класса, то в зависимости от того, на объект какого производного класса указывает указатель базового класса, будут вызываться различные варианты виртуальной функции. Вы объявляете функцию виртуальной внутри базового класса, предваряя ее объявление ключевым словом virtual. Когда виртуальная функция переопределяется в производном классе, нет необходимости повторять ключевое слово virtual (хотя не будет ошибкой и его повторение).