Автор: Пользователь скрыл имя, 08 Ноября 2011 в 12:07, шпаргалка
Работа содержит ответы на вопросы по дисциплине "Программирование".
void virtual print()
{cout<<s<<endl;}
void virtual area()=0;
};
class Circle : public Shape
{ int r;
public:
Circle(char *name,int r): Shape(name)
{ cout << " конструктор класса Circle "<<endl;
this->r=r;
}
~Circle()
{ cout << " деструктор класса Circle " << endl;}
void area();
};
void Circle::area()
{ s=r*r*3.14; cout<<" Площадь круга = "; this->print();
}
int main()
{ Shape *fg1;
fg1=new Circle("("Круг ",2); fg1->area(); delete fg1; return 0;
}
В случае если деструктор базового класса не являлся бы виртуальным, то
при удалении объектов производных классов осуществлялся бы вызов только
деструктора класса соответствующего ему типа , т.е. базового класса (класса,
для которого объявлен соответствующий указатель).
Если в классе имеются виртуальные функции, то желательно объявлять
деструктор этого класса также виртуальным, даже если этого не требуется. Это
может предотвратить возможные ошибки.
42.Параметризированные классы (шаблоны).
Параметризированный класс – некоторый шаблон, на основе которого
можно строить другие классы. Этот класс можно рассматривать как некоторое
описание множества классов, отличающихся только типами их данных. В С++
используется ключевое слово template для обеспечения параметрического
полиморфизма.
Параметрический полиморфизм
тот же код относительно различных типов (параметров тела кода). Это
наиболее полезно при определении контейнерных классов. Шаблоны
определения класса и шаблоны определения функции позволяют многократно
использовать код, корректно по отношению к различным типам, позволяя
компилятору автоматизировать процесс реализации типа.
template <class T1, class T2>
class A
{
T1 i;
T2 j;
public:
A(T1 a, T2 b) {i=a;j=b;}
void show() {cout<<i<<' '<<j<<endl;}
};
int main()
{
A <int,double> ob1(10,0.23);
A <char,char*> ob2('q',"qwert");
ob1.show();
ob2.show();
return 0;
}
43.Шаблоны функций.
Функция, вычисляющей сумму нескольких аргументов.
#include <iostream>
using namespace std;
#include <string.h>
template <class T1,class T2>
T1 sm(T1 a,T2 b) // описание шаблона
{ return (T1)(a+b); // функции c двумя параметрами
}
template <class T1,class T2,class T3>
T1 sm(T1 a,T2 b,T3 c)
// описание шаблона функции
{ return (T1)(a+b+c); // функции c тремя параметрами
}
int main()
{cout<<"вызов функции sm(int,int) = "<<sm(4,6)<<endl;
cout<<"вызов функции sm(int,int,int) = "<<sm(4,6,1)<<endl;
cout<<"вызов функции sm(int,double) = "<<sm(5,3)<<endl;
cout<<"вызов функции sm(double,int,short)= " <<
sm(.4,6,(short)1)<<endl;
// cout<<sm("я изучаю","язык С++")<<endl; error cannot add two pointers
return 0;
}
44.Передача в шаблон класса дополнительных параметров.
При создании экземпляра класса из шаблона в него могут быть переданы не только типы, но и переменные и константные выражения:
#include <iostream>
using namespace std;
template <class T1,int i=0,class T2>
class cls
{ T1 a;
T2 b;
public:
cls(T1 A,T2 B) : a(A),b(B){}
~cls(){}
T1
sm() //описание шаблона
функции суммирования
{ // i+=3; // error member function 'int __thiscall cls<int,2>::sm(void)'
return (T1)(a+b+i); //a=b+i; return a;
}
};
int main()
{ cls <int,1,int> obj1(3,2); // в шаблоне const i инициализируется 1
cls <int,0,int> obj2(3,2,1); // error 'cls<int,0>::cls<int,0>':no overloaded
cls <int,int,int> obj13(3,2,1); // error 'cls' : invalid template argument for 'i',
cls <int,int> obj2(3,1); // error (аналогично предыдущей)
cout<<obj1.sm()<<endl;
return 0;
}
Результатом работы программы будет выведенное на экран число 6.
В этой программе инструкция template <class T1,int i=0,class T2> гово-
рит о том, что шаблон класса cls имеет три параметра, два из которых − имена
типов (Т1 и Т2), а третий (int i=0) − целочисленная константа. Значение кон-
станты i может быть изменено при описании объекта cls <int,1,int> obj1(3,2). В
этом случае инициализация константы i в инструкции template не требуется
template <class T1,int i,class T2>
44.Совместное использование шаблонов и наследования.
Шаблонные классы, как и обычные, могут использоваться повторно.
Шаблоны и наследование представляют собой механизмы повторного использования кода и могут включать полиморфизм. Шаблоны и наследования связаны между собой следующим образом:
- шаблон класса может быть порожден от обычного класса;
- шаблонный класс может быть производным от шаблонного класса;
- обычный класс может быть производным от шаблона класса.
Ниже приведен пример простой программы, демонстрирующей наследование шаблонного класса oper от шаблонного класса vect.
#include <iostream>
using namespace std;
template <class T>
class vect
{protected:
T *ms;
int size; // размерность массива-вектора
public:
vect(int n) : size(n) // конструктор
{ ms=new T[size];}
~vect(){delete [] ms;} // деструктор
T &operator[](const int ind) // доопределение операции []
{ if((ind>0) && (ind<size)) return ms[ind];
else return ms[0];
}
};
template <class T>
class oper : public vect<T>
// класс операций над вектором
{ public:
oper(int n): vect<T>(n) {} // конструктор
~oper(){}
void print()
{ for(int i=0;i<size;i++)
cout<<ms[i]<<' ';
cout<<endl;
}
};
int main()
{ oper <int> v_i(4); // int-вектор
oper <double> v_d(4); // double-вектор
v_i[0]=5; v_i[1]=3; v_i[2]=2; v_i[3]=4; // инициализация int
v_d[0]=1.3; v_d[1]=5.1; v_d[2]=.5; v_d[3]=3.5; // инициализация double
cout<<"int вектор = ";
v_i.print();
cout<<"double вектор = ";
v_d.print();
return 0;
}
Как следует из примера, реализация производного класса от класса-шаблона в основном ничем не отличается от обычного наследования.
45.Шаблоны класса и friend.
Для шаблонов класса, как и для обычных классов, могут быть установлены отношения дружественности. Дружественность может быть установлена между шаблонным классом и глобальной функцией, функцией-членом другого (возможно шаблонного класса) или целым классом (возможно шаблонным).
(ПРИМЕР ИЗ КОНСПЕКТА, НО ВЫДАЁТ ОШИБКУ)
template <class T>
class B;
template <class T>
class A
{
T *m;
int size;
public:
A(int size, T *m);
~A();
friend T fun1 (T&);
friend T B<T>::fun2(B<T> &);
};
template <class T>
class B
{
public:
T fun2(B<T> &);
};
template <class T>
void fun1(T &obj)
{
}
int main()
{
int m1[]={1,2,3};
A <int> a1(3,m1);
fun1(a1);
return 0;
}
46.Реализация smart-указателя.
Если при использовании в программе указателя на объект, память для которого выделена с помощью оператора new, объект становится не нужен, то для его разрушения необходимо явно вызвать оператор delete. В то же время на один объект могут ссылаться множество указателей и, следовательно, нельзя однозначно сказать, нужен ли еще этот объект или он уже может быть уничтожен.
template <typename T>
struct Status { T *RealPtr; int Count;
};
template <typename T>
class Point
{ Status <T> *StatPtr;
Public: