Примеры для подготовки к коллоквиуму по С++, страница 2
Описание файла
Документ из архива "Примеры для подготовки к коллоквиуму по С++", который расположен в категории "". Всё это находится в предмете "практикум (прикладное программное обеспечение и системы программирования)" из 4 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Онлайн просмотр документа "Примеры для подготовки к коллоквиуму по С++"
Текст 2 страницы из документа "Примеры для подготовки к коллоквиуму по С++"
int t;
//...
};
void gg ( C *pc )
{
pc -> a = 11; // неоднозначность
pc -> f ( 111 ); // неоднозначность
pc -> g (); // неоднозначность
pc -> g = 12; // неоднозначность
pc -> h (); // B::h()
pc -> h ( 13 ); // B::h(int)
pc -> h ( 'a' ); // нет доступа к B::h(char)
}
int main()
{
C c;
C *pc = &c;
gg ( pc );
c.a = 11; // неоднозначность
c.f ( 111 ); // неоднозначность
c.g (); // неоднозначность
c.g = 12; // неоднозначность
c.h (); // B::h()
c.h ( 13 ); // B::h(int)
c.h ( 'a' ); // нет доступа к B::h(char)
return 0;
}
Пример №1
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются (считаем, что все объявленные функции где-то описаны).
class M
{
public:
int m;
};
class N
{
public:
int n;
void g ();
};
struct A: M, virtual N
{
char g ( char );
};
struct B: M, virtual N
{
void g ( int );
};
class D: public A, public B
{
public:
void f ();
};
void D::f ()
{
char c = 'a';
A::m = 1;
n = 1;
c = g ( с );
g ( 2 );
g ();
}
Можно ли исправить ошибки (если они есть), изменяя только описание функции D::f()? Если можно, то каким образом?
Пример №2
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются (считаем, что все объявленные функции где-то описаны).
class V
{
public:
int v;
void x ( int );
};
class A
{
public:
int a;
};
struct B: A, virtual V
{
double x;
};
struct C: A, virtual V
{
char x;
};
class D: public B, public C
{
public:
void f ();
};
void D::f ()
{
v = 1;
a = 1;
x ( 6 );
x = 1.2;
x = 'a';
}
Можно ли исправить ошибки (если они есть), изменяя только описание функции D::f()? Если можно, то каким образом?
Тема 6. Перегрузка функций
На лекции (2 поток) были рассмотрены следующие примеры:
-
для 2-ого шага алгоритма поиска оптимально отождествляемой функции (best matching) (целочисленные расширения и float → double)
-
void f ( int );
-
void f ( double );
-
-
void g ()
-
{
-
short aa = 1;
-
float ff = 1.0;
-
-
f ( ff ); // f (double)
-
f ( aa ); // f (int)
}
— неоднозначности нет, т.к. расширения предпочтительнее других стандартных преобразований
-
для 3-ого шага алгоритма (все остальные стандартные преобразования)
-
void f ( char );
-
void f ( double );
-
-
void g ()
-
{
-
// ...
-
f ( 0 ); // неоднозначность, т.к. преобр. int --> char и int --> double равноправны
}
-
для 4-ого шага алгоритма (пользовательские преобразования)
-
struct S
-
{
-
S ( long ); // long --> S
-
operator int (); // S --> int
-
// ...
-
};
-
-
void f ( long );
-
void f ( char* );
-
void g ( S );
-
void g ( char* );
-
-
void ex ( S &a )
-
{
-
f ( a ); // O.K. f ( (long) ( a.operator int()) );
-
g ( 1 ); // O.K. g ( S ( (long) 1) );
-
g ( 0 ); // O.K. g ( (char*) 0); т.е. g (char*) - но! на шаге 3
}
Замечание 1
Пользовательские преобразования применяются неявно только в том случае, если они однозначны!
class B
{
// ...
public:
B ( int );
operator int ();
B operator+ ( const B& );
// ...
};
void ex ()
{
B x ( 1 );
... x + 1 ... // неоднозначность, т.к. возможно x.operator int()+1 либо x.operator+(B(1))
}
Замечание 2
Допускается не более одного пользовательского преобразования!
class X
{
// ...
public:
operator int ();
// ...
};
class Y
{
// ...
public:
operator X ();
};
void f ()
{
Y a;
int b;
b = a; // ошибка, т.к. требуется a .operator X().operator int()
}
Замечание 3
Помните об explicit-конструкторах!
struct S
{
explicit S ( long ); // long --> S, но только при явном вызове конструктора
operator int (); // S --> int
// ...
};
void f ( long );
void f ( char* );
void g ( S );
void g ( char* );
void ex ( S &a )
{
f ( a ); // O.K. f ( (long) ( a.operator int()) );
g ( 1 ); // ОШИБКА, надо явно g ( S (1) );
g ( 0 ); // O.K. g ( (char*) 0); т.е. g (char*) - но! на шаге 3
}
-
для 5-ого шага алгоритма (отождествления по многоточию)
-
class R
-
{
-
// ...
-
public: R ( double );
-
// ...
-
};
-
void f ( int, R );
-
void f ( int ... );
-
void g ()
-
{
-
f ( 1, 1 ); // O.K. f (int, R);
-
f ( 1, "abc" ); // O.K. f (int ...);
}
Пример №1
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются. Вычеркните ошибочные конструкции (если они есть). Что будет напечатано при вызове функции main()?
class complex
{
double re, im;
public:
complex ( double r = 0, double i = 0) { re = r; im = i; }
operator double () { return re; }
double get_re () { return re; }
void print () const { cout << "re=" << re << " im=" << im << endl; }
};
double f ( double x, int i )
{
cout << "f(double x, int i)" << endl;
return x*i;
}
complex f ( complex z, int i )
{
cout << "f(complex z, int i)" << endl;
return complex ( z.get_re()*i );
}
int main ()
{
complex z ( 7, 5 ), y;
double x = 1.5, t = 2.8;
y = f ( z, 2 );
cout << "y = ";
y.print();
t = f ( z, t );
cout << "t = " << t << endl;
y = f ( x, 4 );
cout << " y= ";
y.print();
y = f ( z, z );
cout << "y = ";
y.print();
cout << "choice is done!" << endl;
return 0;
}
Пример №2
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются. Вычеркните ошибочные конструкции (если они есть). Что будет напечатано при вызове функции main()?
class complex
{
double re, im;
public:
explicit complex ( double r, double i = 0 ) { re = r; im = i; }
complex () { re = 0; im = 0; }
operator double () { return re; }
double get_re () { return re; }
void print () const { cout << "re=" << re << " im=" << im << endl; }
};
double f ( complex z, int i )
{
cout << "f(complex z, int i)" << endl;
return z.get_re() * i;
}
int f ( complex x, complex y )
{
cout << "f(complex x, complex y)" << endl;
return x.get_re() * y.get_re();
}
complex f ( complex x, double t )
{
cout << "f(complex x, double t)" << endl;
return complex ( x.get_re() * t );
}
int main ()
{
complex a ( 2, 3 ), b ( 4, 7 );
double x = 1.5;
int i = 15;
x = f ( a, x );
cout << "x = " << x << endl;
x = f ( x, a );
cout << "x = " << x << endl;
b = f ( complex ( i ), a );
cout << "b = ";
b.print ();
x = f ( b, ' a' );
cout << "x = " << x << endl;
cout << "choice is done!" << endl;
return 0;
}
Тема 7. Шаблоны функций
Пример №1
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются. Ошибочные конструкции вычеркните из текста программы. Что будет напечатано при вызове функции main()?
class complex
{
double re, im;
public:
complex ( double r = 0, double i = 0 )
{
re = r;
im = i;
cout << "constructor" << endl;
}
operator double ()
{
cout << "operator double " << endl;
return re;
}
double get_re () { return re; }
void print () const { cout << "re=" << re << " im=" << im << endl; }
};
template <class T>
T f ( T& x, T& y )
{
cout << "template f" << endl;
return x > y ? x : y;
}
double f ( double x, double y )
{
cout << "ordinary f" << endl;
return x > y ? -x : -y;
}
int main ()
{
complex a ( 2, 5 ), b ( 2, 7 ), c;
double x = 3.5, y = 1.1;
int i, j = 8, k = 10;
c = f ( a, b );
cout << "c = ";
c.print ();
x = f ( a, y );
cout << "x = " << x << endl;
i = f ( j, k );
cout << "i = " << i << endl;
cout << "choice is done!" << endl;
return 0;
}
Пример №2
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются. Ошибочные конструкции вычеркните из текста программы. Что будет напечатано при вызове функции main()?
template <class T>
T max (T& x, T& y)
{
return x > y ? x : y;
}
int main ()
{
double x = 1.5, y = 2.8, z;
int i = 5, j = 12, k;
char *s1 = "abft";
char *s2 = "abxde", *s3;
z = max ( x, y );
cout << "z = "<< z << endl;
k = max <int>(i, j);
cout << "k = "<< k << endl;
z = max (x, i);
cout << "z = "<< z << endl;
z = max <double> ( y, j );
cout << "z = "<< z << endl;
s3 = max (s1, s2);
cout << "s3 = "<< s3 << endl;
cout << "choice is done!" << endl;
return 0;
}
Перегрузите шаблонную функцию max так, чтобы сравнение строк осуществлялось лексикографически (т.е. в соответствии с кодировкой символов).
Теоретические вопросы
В программу коллоквиума будут входить и теоретические вопросы по С++:
Пример №1
Какие из следующих утверждений являются верными, а какие — ошибочными? Объясните, в чем заключаются эти ошибки.
-
имя объекта класса не может совпадать с именем члена этого класса
-
если функция в базовом классе и в его производном имеет один и тот же профиль и тип возвращаемого значения, то она становится виртуальной
-
если в классе все описанные конструкторы имеют параметры, то компилятор автоматически сгенерирует конструктор умолчания
-
если базовый класс является абстрактным, то в производном классе необходимо описать все его чистые виртуальные функции;
-
одноместная операция может быть перегружена функцией-членом без параметров
-
throw без выражения может появиться только в try-блоке, где есть обработчик вида catch (...){ } и т.п.
Пример №2
Перечислите все ситуации, когда вызывается деструктор класса. Приведите примеры каждой из этих ситуаций.
Пример №3
Что произойдет, если в процессе «свертки стека» деструктором класса будет возбуждено исключение? ...и т.д.