Примеры для подготовки к коллоквиуму по С++
Описание файла
Документ из архива "Примеры для подготовки к коллоквиуму по С++", который расположен в категории "". Всё это находится в предмете "практикум (прикладное программное обеспечение и системы программирования)" из 4 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Онлайн просмотр документа "Примеры для подготовки к коллоквиуму по С++"
Текст из документа "Примеры для подготовки к коллоквиуму по С++"
Примеры для подготовки к коллоквиуму по С++
-
Абстракция и инкапсуляция: классы и объекты
-
Перегрузка операторов
-
Обработка исключений
-
Виртуальные функции
-
Множественное наследование
-
Перегрузка функций
-
Шаблоны функций
Тема 1. Абстракция и инкапсуляция: классы и объекты
Пример №1
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются.
class A
{
int a, b;
public:
A ( A &x ) { a = x.a; b = x.b; cout << 1; }
A ( int a ) { this->a = a; b = a; cout << 2; }
};
void f ()
{
A x ( 1 );
A y;
A z = A ( 2, 4 );
A t ( 3.5, 2 );
A s = 6;
A w = z;
t = z = w;
}
Как нужно изменить описание класса A (не изменяя описания функции f), чтобы в f() не было ошибок? Что будет напечатано в результате работы функции f()?
Обязательное требование: нельзя добавлять новые функции-члены класса A, но допустимы любые изменения в уже имеющихся.
Пример №2
Написать конструктор для некоторого класса A таким образом, чтобы были выполнены следующие условия:
-
это единственный явно описанный конструктор класса A,
-
верны следующие описания объектов класса A:
-
A a;
-
A b ( 1 );
-
A c ( 1, 2 );
A d ( '1', 1 );
Пример №3
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются. Вычеркните ошибочные конструкции (если они есть). Что будет напечатано при вызове функции f()?
class A
{
int a;
public:
A ( int x ) { a = x; cout << 1; }
A ( int x, int y ) { a = x / y; cout << 2; }
A ( int x, int y, int z = 1 ) { a = (x+y) / z; cout << 3; }
~A () { cout << 4; }
void operator = ( A &b ) { a = b.a; cout << 5; }
};
void f ()
{
A x;
A y ( 1 );
A z ( 1, 2 );
A t ( 1, 2, 3 );
A w = 4;
A v = y;
y = t = v;
}
Пример №4
Для класса string опишите конструктор копирования и операцию присваивания с объявленными профилями, реализующие «глубокое» («содержательное») копирование объектов этого класса. Объясните, почему был выбран именно такой вариант объявления этих функций-членов класса.
class string
{
char *p;
int size;
public:
string ( const char *str )
{
p = new char [(size = strlen ( str )) + 1];
strcpy ( p, str );
}
~string () { delete[]p; }
string ( const string &a );
string& operator= ( const string &a );
};
Тема 2. Перегрузка операторов
Пример №1.
Для класса rational опишите перегруженную операцию умножения так, чтобы были верными все действия функции g(). Возможно ли это? Если нет — объясните почему; если можно - опишите и объясните, какие действия будут выполняться при вызове функции g()? Если возможно несколько вариантов решения этой задачи, то укажите их все.
class rational
{
int p, q;
public:
rational ( int a , int b )
{
p = a;
q = b;
}
// ...
};
void g ()
{
rational x ( 1, 2), y ( 4, 5 ), z ( 1, 1 );
const rational w ( 1, 8 );
int t = 3;
z = x * y;
z = w * y;
z = y * w;
z = z * t;
z = t * z;
}
Пример №2
Для класса rational опишите перегруженную операцию инкремента (префиксный и постфиксный варианты) так, чтобы были верными все действия функции g(). Семантика этой операции — увеличение на 1 значений полей p и q. Возможно ли это? Если нет — объясните почему; если можно — опишите и объясните, какие действия будут выполняться при вызове функции g()? Если возможно несколько вариантов решения этой задачи, то укажите их все.
class rational
{
int p, q;
public:
rational ( int a, int b )
{
p = a;
q = b;
}
// ...
};
void g ()
{
rational x ( 1, 2 ), z ( 1, 1 );
const rational y ( 1, 8 );
z = x++;
z = y++;
z = ++x;
z = ++y;
}
Возможно ли для объектов класса rational с перегруженной вами операцией инкремента следующее:
z = x++ ++;
z = ++ ++x;
Если возможно, то опишите последовательность действий при выполнении этих операторов и укажите, чему равны значения x и z. Если невозможно, то объясните почему.
Пример №3
Для класса string опишите перегруженную операцию конкатенации так, чтобы были верными все действия функции g(). Возможно ли это? Если нет — объясните почему; если можно — опишите и объясните, какие действия будут выполняться при вызове функции g()? Если возможно несколько вариантов решения этой задачи, то укажите их все.
class string
{
char *p;
int size;
public:
string ( const char *str)
{
p = new char [(size = strlen(str)) + 1];
strcpy( p, str );
}
string ( const string &a )
{
p = new char [(size = a.size) + 1];
strcpy ( p, a.p );
}
~string ()
{
delete[] p;
}
string& operator= ( const string &a )
{
if ( this == &a ) return *this;
delete [] p;
p = new char [(size = a.size) + 1];
strcpy ( p, a.p );
return *this;
}
};
void g ()
{
string s1 ( "11111" );
string s2 = s1;
string s3 ( "222222222" );
const string s4 ( "4444444" );
// ...
s1 = s2 + s3;
s1 = s3 + s4;
s1 = s4 + s3;
s1 = s3 + "abcd";
}
Пример №4
Для класса string опишите перегруженную операцию * так, чтобы были верными все действия функции g(). Результат умножения строки s на целое число n (и целого числа n на строку s) — это строка, полученная в результате конкатенации n строк s. Возможно ли это? Если нет — объясните почему; если можно — опишите и объясните, какие действия будут выполняться при вызове функции g()? Если возможно несколько вариантов решения этой задачи, то укажите их все.
class string
{
char *p;
int size;
public:
string ( const char *str )
{
p = new char [(size = strlen(str)) + 1];
strcpy ( p, str );
}
string ( const string &a )
{
p = new char [(size = a.size) + 1];
strcpy ( p, a.p );
}
~string () { delete[] p; }
string& operator= ( const string &a )
{
if ( this == &a ) return *this;
delete [] p;
p = new char [(size = a.size) + 1];
strcpy ( p, a.p );
return *this;
}
};
void g ()
{
string s1 ( "11111" );
string s2 = s1;
const string s3 ( "222222222" );
int t = 5;
// ...
s1 = s2 * t;
s1 = t * s2;
s1 = s3 * t;
s1 = t * s3;
s1 = s2 * 3;
}
Тема 3. Обработка исключений
Пример №1
Что будет выдано в стандартный канал вывода при вызове функции main()? Объясните ответ.
void f ( char c )
{
try
{
if ( c >='1' && c<='9')
c++;
else
throw "error";
try
{
if ( c == '8' )
throw c;
c++;
}
catch ( const char *c )
{
cout << c << "\ncatch1\n";
}
catch ( char c )
{
cout << "catch2\n";
throw;
}
cout << c << endl;
}
catch ( int k )
{
cout << k << "\ncatch3\n";
}
catch ( char *c )
{
cout << c << "\ncatch4\n";
}
}
int main ()
{
try
{
f ( 'a' );
f ( '2' );
f ( '7' );
f ( '5' );
}
catch ( char c )
{
cout << c << "\ncatch5\n";
}
catch ( ... )
{
cout << "all exceptions\n";
};
return 0;
}
Пример №2
Что будет выдано в стандартный канал вывода при вызове функции main()? Объясните ответ.
class X
{
int j;
public:
X ( int k )
{
try
{
if ( k == 10 ) throw k;
if ( k == 0 ) throw '0';
j = k;
}
catch ( char )
{
cout << "catch1\n";
}
catch (...)
{
cout << "catch2\n";
throw;
}
}
};
void f ( int i )
{
try
{
X a ( i );
X b ( 5 );
}
catch ( int )
{
cout << "catch3\n";
throw;
}
catch (...)
{
cout << "catch4\n";
}
}
int main ()
{
try
{
f ( 0 );
f ( 10 );
f ( 100 );
}
catch ( int )
{
cout << "catch5\n";
};
return 0;
}
Тема 4. Виртуальные функции
Пример №1
Есть ли ошибки в приведенном фрагменте программы на С++? Если есть, то объясните, в чем они заключаются. Ошибочные конструкции вычеркнуть из текста программы. Какие функции будут вызваны при вызове функции g()?
class A
{
public:
void f1 () { cout << "f1_A" << endl; }
virtual void f1 ( const int c ) { cout << "f1_A_int" << endl; }
virtual void f2 () { cout << "f2_A" << endl; }
virtual int f3 ( const int k ) { cout << "f3_A" << endl; return k + 10; }
};
class D: public A
{
public:
void f1 () { cout << "f1_D" << endl; }
virtual void f1 ( const char x ) { cout << "f1_D_char" << endl; }
void f2 () { cout << "f2_D" << endl; }
virtual void f3 ( const int a ) { cout << "f3_D" << endl; }
};
void g ()
{
A x;
D y;
A *p = &x;
p->f1 ();
p->f1 ( '1' );
p->f1 ( 1 );
p->f2 ();
p->f3 ();
p = &y;
p->f1 ();
p->f1 ( '1' );
p->f1 ( 1 );
p->f2 ();
p->f3 ();
}
Пример №2
Что будет напечатано в результате вызова функции main() в следующем фрагменте программы на Си++?
class B
{
public:
void f () { cout << "B::f\n"; }
virtual void g () { cout << "B::g\n"; }
void h () { cout << "B::h\n"; }
};
class D : public B
{
public:
void f () { cout << "D::f\n"; }
void g () { cout << "D::g\n"; }
virtual void h () { cout << "D::h\n"; }
};
void P ( B * pb, D * pd )
{
pb->f ();
pb->g ();
pb->h ();
pd->f ();
pd->g ();
pd->h ();
}
int main ()
{
P ( new B, new D );
P ( new D, new D );
return 0;
}
Тема 5. Множественное наследование
На лекции (2 поток) был рассмотрен пример, подобный этому:
class A
{
public:
int a;
void g () { cout << "A::g" << endl; }
void f () { cout << "A::f" << endl; }
};
class B
{
int a;
void h ( char ) { cout << "B::h - char" << endl; }
public:
int g;
void f ( int v ) { cout << "B::f" << endl; }
void h () { cout << "B::h - void" << endl; }
void h ( int ) { cout << "B::h - int" << endl; }
};
class C: public A, public B
{