игра брюс 2048
Главная / Программирование / Программирование на С/С++ / Тест 94

Программирование на С/С++ - тест 94

Упражнение 1:
Номер 1
Какие утверждения о шаблонах в языке С++ верны?

Ответ:

 (1) шаблонными могут быть не только классы или функции, но и структуры 

 (2) степень обобщённости класса зависит от количества параметров шаблона 

 (3) обобщённое программирование реализуется в языке С++ через шаблоны 

 (4) шаблон класса позволяет автоматически создавать конкретный класс по обобщённому описанию класса 

 (5) использование шаблонов позволяет сократить размер исполняемого файла 


Номер 2
Какие утверждения о параметрах шаблонов верны?

Ответ:

 (1) параметрами шаблона могут быть типы и константы 

 (2) параметры шаблона константы могут быть числовыми и строчными 

 (3) параметры шаблона могут иметь значения по умолчанию 

 (4) задание значений параметров шаблона происходит при конкретизации шаблона 

 (5) при конкретизации шаблона некоторые параметры можно оставлять неопределёнными 


Номер 3

		//====================== start of sample.cpp ==========================
		#include <vector>
		
		template <class Storage, int size>
		class Input
		{
		public:
			Input()
			: m_store(size) {}
		
		private:
		   Storage m_store;
		};
		
		int main()
		{
			Input<int,5> a1;
			Input<int,6> a2;
			Input<std::vector<int>,10> v3;
			Input<std::vector<short>,10> v4;
			Input<double, 30> *pMyInput = nullptr;
			return 0;
		}
		//======================  end of sample.cpp  ==========================
                
]]>Сколько описаний пользовательских типов будет в скомпилированном коде из файла sample.cpp?
Ответ:

 (1)

 (2)

 (3)

 (4)

 (5)


Упражнение 2:
Номер 1
Какой код приводит к появлению конкретизированного кода метода в исполняемом файле?

Ответ:

 (1) взятие адреса конкретизированного метода класса  

 (2) взятие адреса конкретизированного объекта класса 

 (3) объявление специализации объекта класса 

 (4) объявление указателя на конкретизированный объект класса, с присвоением ему nullptr 


Номер 2

		//====================== start of sample.cpp ==========================
		template <class Element, unsigned long max_size>
		class Storage {
		public:
			Storage(Element) {}
		};
		
		template <class Element>
		class Storage <Element, 0 /* unlimited*/> {
		public:
			Storage(Element e) {}
		};
		
		template <unsigned long max_size>
		class Storage <int, max_size> {
		public:
			Storage(int e) {}
		};
		
		template <>
		class Storage<char*, 0>
		{
		public:
			Storage(char* s) {}
		};
		
		template <>
		class Storage<char*, 100> {
		public:
			Storage(char* s) {}
		};
		
		int main()
		{
			int p1=4;
			Storage<int, 5> st1(p1);
			Storage<char*, 100> st2(char* s);
			Storage<double, 80000> st3(double n);
			Storage<double, 0> st4(double n);
		
			return 0;
		}
		//======================  end of sample.cpp  ==========================
                
]]>Какой из шаблонов Storage в файле sample.cpp не задействован в функции main в файле sample.cpp?
Ответ:

 (1) template <class Element, unsigned long max_size> class Storage 

 (2) template <class Element> class Storage <Element, 0> 

 (3) template <unsigned long max_size> class Storage <int, max_size> 

 (4) template <> class Storage<char*, 0> 

 (5) template <> class Storage<char*, 100> 


Номер 3

		//====================== start of sample3.h ==========================
		#include <list>
		#include <vector>
		
		template<class Storage>
		class MyIter {};
		
		template<class Storage>
		void my_input_process(Storage* in_item) {}
		
		template<class Storage, int size> void clear_all(Storage*);
		
		template <class Storage, class Element, int size>
		class BackupInput {};
		
		template <class Storage, class Element, int size>
		class Input
		{
		public:
			Input()
			: m_store(size) {}
		
			friend class MyIter<Storage>;
			friend void my_input_process<Storage>(Storage*);
			friend void clear_all<Storage, 100>(Storage*);
			friend class BackupInput<Storage, Element, size>;
		private:
		   Storage m_store;
		};
		
		Input<std::list<short>, short, 25> input25;
		
		int main()
		{
			MyIter<std::list<short>> my_iter;
			BackupInput<std::list<short>, short, 25> backup_input;
		
			my_input_process<std::vector<short>>(nullptr);
			clear_all<std::vector<short>, 25>(nullptr);
			clear_all<std::list<short>, 100>(nullptr);
			return 0;
		}
		//======================  end of sample3.h  ==========================
                
]]>Какие функции и классы в файле sample.cpp имеют доступ к всем атрибутам глобального объекта input25?
Ответ:

 (1) my_iter 

 (2) backup_input 

 (3) my_input_process<std::vector<short>>() 

 (4) clear_all<std::vector<short>, 25>(nullptr); 

 (5) clear_all<std::list<short>, 100>(nullptr); 


Упражнение 3:
Номер 1

		//====================== start of sample.cpp ==========================
		template<unsigned long N>
		class binary
		{
		public:
			static unsigned long const value =
					binary<N / 10>::value << 1 | N % 10;
		};
		
		template<>
		class binary<0>
		{
		public:
			static unsigned long const value = 0;
		
		};
		
		int main(int argc, char* argv[])
		{
			if (argc > 1)
			{
				static unsigned const two = binary<10>::value;
			}
			return 0;
		}
		//======================  end of sample.cpp  ==========================
                
]]>Когда будет посчитано значение переменной two?
Ответ:

 (1) после успешной проверки условия argc 

 (2) при начале выполнения функции main 

 (3) при загрузке программы с оперативную память 

 (4) при компиляции программы 


Номер 2

		//====================== start of sample.cpp ==========================
		template<unsigned long N>
		class binary
		{
		public:
			static unsigned long const value =
					binary<N / 10>::value << 1 | N % 10;
		};
		
		template<>
		class binary<0>
		{
		public:
			static unsigned long const value = 0;
		};
		
		int main(int argc, char* argv[])
		{
			static unsigned const xyz = binary<111>::value;
			return 0;
		}
		//======================  end of sample.cpp  ==========================
                
]]>Конкретизация шаблона с значением 111 приводит:
Ответ:

 (1) к рекурсивной конкретизации шаблона с параметрами 10, 1, 0 

 (2) к последовательной трёхкратной конкретизацией шаблона с параметрам 1 

 (3) к рекурсивной конкретизации шаблона с параметрами 11, 1, 0 

 (4) к рекурсивной конкретизации шаблона с параметрами 11, 1, 1 


Номер 3

		//====================== start of sample.cpp ==========================
		template<unsigned long N>
		class binary
		{
		public:
			static unsigned long const value =
					binary<N / 10>::value << 1 | N % 10;
		};
		
		template<>
		class binary<0>
		{
		public:
			static unsigned long const value = 0;
		};
		
		template<>
		class binary<1>
		{
		public:
			static unsigned long const value = 1;
		};
		
		int main(int argc, char* argv[])
		{
			static unsigned const x0 = binary<0>::value;
			static unsigned const x1 = binary<1000>::value;
			static unsigned const x2 = binary<1001>::value;
			static unsigned const x3 = binary<1010>::value;
			static unsigned const x4 = binary<1011>::value;
			return 0;
		}
		//======================  end of sample.cpp  ==========================
                
]]>При инициализации какой переменной не будет использоваться конкретизация шаблона с параметром 0?
Ответ:

 (1) x0 

 (2) x1 

 (3) x2 

 (4) x3 

 (5) x4 


Упражнение 4:
Номер 1
Специализация класса позволяет:

Ответ:

 (1) переопределить методы шаблона для заданных конкретизаций шаблона 

 (2) доопределить дополнительные методы и члены класса для заданных конкретизаций шаблона 

 (3) встроить специализированный шаблон в другую иерархию классов 

 (4) определять тип объекта по указателю на базовый класс 


Номер 2
Какие утверждения о идиоме SFINAE верны?

Ответ:

 (1) сутью идиомы SFINAE является избежание ошибок компиляции при перегрузке функций путём отбрасывания неподходящих шаблонов из списка кандидатов на подходящую перегрузку 

 (2) идиома SFINAE поддерживается компилятором и препроцессором языка С++ 

 (3) идиома SFINAE работает при автоматическом выводе типа шаблона по аргументам функции 

 (4) при SFINAE рассматривается не только заголовок, но и тело функции (метода) 


Номер 3
Библиотека boost::type_traits позволяет:

Ответ:

 (1) определять наличие у класса требуемых методов 

 (2) задавать различные специализации шаблонов в зависимости от того: это пользовательский класс или базовый тип 

 (3) отличать указатель на объект от типа во время компиляции 

 (4) выдавать ошибки компиляции при несоответствии типа функции, в которой объект этого типа используется 


Упражнение 5:
Номер 1

	//====================== start of sample.cpp ==========================
		template<typename T>
		typename T::difference_type my_diff( T& v1,  T& v2);
		
		template<typename T>
		T my_diff2(T& v1, T& v2);
		
		class A {
		public:
			A(int in = 5);
			typedef short difference_type;
			difference_type operator-(A&);
		};
		
		int main()	{
			A i(5);
			A j(10);
			my_diff(i,j);
			int x = 5;
			int y = 10;
			my_diff(x,y);
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>Какие проблемы может решить использование идиомы SFINAE в вышеприведённом коде?
Ответ:

 (1) проверка соответствия тела функции и необходимых методов класса 

 (2) исключение из списка подстановки для типа А перегрузок, которые не используют тип T::difference_type 

 (3) получение ошибки компиляции при отсутствии в шаблоне типа T::difference_type 

 (4) избежание ошибок компиляции, которые могут случиться при перегрузке функции неподходящим шаблоном 


Номер 2

	//====================== start of sample.cpp ==========================
		#include <type_traits >
		class A		{
		public:
			A(int in = 5);
		};
		
		int main()
		{
			std::is_pointer<A> is_ptr;
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>Как может использоваться объявление переменной is_ptr?
Ответ:

 (1) если А не указатель, то код не соберётся 

 (2) можно обратится к статическому атрибуту is_ptr.value и сравнить его с true 

 (3) можно проверить тип is_ptr: он может быть true_type или false_type 

 (4) если А не указатель, то при выполнении программы в месте создания is_ptr возникнет прерывание 


Номер 3

	//====================== start of sample.cpp ==========================
		#include <type_traits>
		class A  {
		public:
			A(int in = 5);
		};
		
		int main() 	{
			std::true_type my_true;
			std::false_type my_false;
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>Какие утверждения о переменных my_true и my_false верны?
Ответ:

 (1) обе переменных принадлежат одной и той же иерархии классов 

 (2) типы обеих переменных получены конкретизацией шаблона integral_constant 

 (3) обе переменных содержат атрибуты true_value и false_value типа bool 

 (4) шаблонная функция, которая возвращает типы true_type или false_type в зависимости от параметров шаблона может использоваться для конкретизации другого шаблона 


Упражнение 6:
Номер 1

	//====================== start of sample.cpp ==========================
		template <typename T>
		struct remove_extend
		{
			typedef T type;
		};
		
		template <typename T, std::size_t N>
		struct remove_extend<T[N]>
		{
			typedef T type;
		};
	//======================  end of sample.cpp  ==========================
                
]]>Что произойдёт если не определять специализированный шаблон remove_extend<T[N]> для массива??
Ответ:

 (1) при использовании типа, порождённого от базового шаблона будет бросаться excetption 

 (2) программа не соберётся из-за ошибки компиляции при подстановке массива в этот шаблон 

 (3) шаблонная структура определит remove_extend::type как Т[N] и этим типом неудобно пользоваться 

 (4) произойдёт резкое увеличение размера исполняемого файла из-за инстанциирования нового типа под каждый размер массива 


Номер 2

	//====================== start of sample.cpp ==========================
		#include <type_traits>
		
		template <typename IT_1, typename IT_2, bool b>
		IT_2 copy_imp(IT_1 first, IT_1 last, IT_2 out,
					  const std::integral_constant<bool, b>&)  {
			while(first != last)  {
				*out = *first;
				++out;
				++first;
			}
			return out;
		}
		
		template <typename T>
		T* copy_imp(const T* first, const T* last, T* out, const std::true_type&) 	{
			memmove(out, first, (last-first)*sizeof(T));
			return out * (last-first);
		}
		
		template <typename I1, typename I2>
		inline I2 copy(I1 first, I1 last, I2 out)  {
			typedef typename std::iterator_traits<I1>::value_type value_type;
			return copy_imp(first, last, out, std::has_trivial_assign<value_type>());
		}
		
		class A {};
		
		int main()
		{
			std::vector<A> vec1;
			std::vector<A> vec2;
			copy(vec1.begin(), vec1.end(), vec2.begin());
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>Какие утверждения про то какая функция копирования copy_impl() будет использована верны?
Ответ:

 (1) выполняется функция, которая требует наличия операции присваивания 

 (2) выполняется функция, реализующая максимально общее решение 

 (3) выполняется функция, реализующая наиболее эффективное решение 

 (4) третьим параметром функции copy_impl() является тип true_type 

 (5) типы параметров first и out должны поддерживать операция разыменования 


Номер 3

	//====================== start of sample.cpp ==========================
		#include <type_traits>
		
		template <typename IT_1, typename IT_2, bool b>
		IT_2 copy_imp(IT_1 first, IT_1 last, IT_2 out,
					  const std::integral_constant<bool, b>&)
		{
			while(first != last)
			{
				*out = *first;
				++out;
				++first;
			}
			return out;
		}
		
		template <typename T>
		T* copy_imp(const T* first, const T* last, T* out, const std::true_type&)
		{
			memmove(out, first, (last-first)*sizeof(T));
			return out * (last-first);
		}
		
		template <typename I1, typename I2>
		inline I2 copy(I1 first, I1 last, I2 out)
		{
			typedef typename std::iterator_traits<I1>::value_type value_type;
		
			return copy_imp(first, last, out, std::has_trivial_assign());
		}
		
		class A {};
		
		int main()
		{
			std::vector<short> arr1;
			std::vector<short> arr2;
			copy(arr1.begin(), arr1.end(), arr2.begin());
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>Какие утверждения про используемую функцию копирования copy_impl() верны?
Ответ:

 (1) выполняется функция, которая требует наличия операции присваивания 

 (2) выполняется функция, реализующая частную реализацию 

 (3) выполняется функция, реализующая наиболее эффективное решение 

 (4) третьим параметром функции copy_impl() является тип false_type 

 (5) типы параметров first и out должны поддерживать операция разыменования 


Упражнение 7:
Номер 1
Какие утверждения о работе с исключениями в языке С/С++ верны?

Ответ:

 (1) исключения используются для обработки нештатных ситуаций времени исполнения программы 

 (2) в качестве классов исключений могут использоваться только пользовательские классы 

 (3) исключения используются для обработки ошибок времени компиляции 

 (4) если исключение не будет поймано, то будет вызвана системная функция terminate() 

 (5) часто в качестве класса исключений используются пустые типы 


Номер 2
Чем отличается обработка ошибок посредством прерываний от проверки кода возврата?

Ответ:

 (1) носителем информации о нештатной ситуации являются объекты заранее продуманной иерархии классов исключений 

 (2) блок кода, обрабатывающий нештатную ситуация при возбуждении исключения может быть размещён на любом вышестоящем по стеку уровне 

 (3) игнорирование кода возврата не приводит к падению приложения 

 (4) обработка ошибок посредством прерываний делает код сложнее 

 (5) обработка ошибок посредством прерываний даёт выигрыш в быстродействии 


Номер 3
Какие утверждения о блоках try и catch верны?

Ответ:

 (1) любое исключение, брошенное из блока try будет поймано в нижележащем блоке catch 

 (2) исключение, брошенное вне блока try функции может быть поймано только в блоках catch вызывающей функции 

 (3) друг за другом могут следовать несколько блоков try подряд 

 (4) друг за другом могут следовать несколько блоков catch подряд 

 (5) исключение, брошенное вне блока try функции может быть поймано только в блоках catch вызывающей функции 

 (6) блоки try могут быть вложенными 


Упражнение 8:
Номер 1

	//====================== start of sample.cpp ==========================
		#include <stdexcept>
		void my_open1()
		{
			throw int(8);
		}
		
		void my_open2()
		try
		{
			throw std::logic_error("");
		}
		catch(std::runtime_error& err) {}
		
		void my_open3()
		try
		{
			throw std::runtime_error(&guot;runtime");
		}
		catch(const std::runtime_error* err) {}
		
		struct ERR_ {};
		
		void my_open4() {
			try
			{
				throw ERR_();
			}
			catch(...) {}
		}
		
		int main() {
			try {
			}
			catch(...) 	{
				return 5;
			}
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>Вызов каких из функций изнутри блока try в функции main() приведёт к завершению программы с результатом 5?
Ответ:

 (1) my_open1() 

 (2) my_open2() 

 (3) my_open3() 

 (4) my_open4() 


Номер 2

	//====================== start of sample.cpp ==========================
		struct A {};
		struct B {};
		struct C {};
		struct D {};
		struct E {};
		struct F {};
		
		int main()
		{
			try
			{
				foo();
			}
			catch(const A& a) {}
			catch(static const B*) {}
			catch(C c) {}
			catch(volatile D* d) {}
			catch(virtual E* e) {}
			catch(F*&) {}
			catch(...)
			{
				return 5;
			}
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>Обработчики исключений какого типа записаны неправильно?
Ответ:

 (1)

 (2)

 (3)

 (4)

 (5)

 (6)


Номер 3

	//====================== start of sample.cpp ==========================
		struct A {};
		struct B {};
		struct C {};
		struct D {};
		struct E {};
		struct F {};
		
		void foo(int i)
			try
			{
				switch(i)
				{
				case 1: throw A();
				case 2: throw B();
				case 4: throw D();
				default:
					throw F();
				}
			}
			catch(A&)  {  }
			catch(B&)  { throw D(); }
			catch(D&)  { throw C(); }
			catch(...) { throw; }
		
		int main(int argc, char* argv[])
		{
			try
			{
				foo(argc);
			}
			catch(const A& a) {}
			catch(const B*) {}
			catch(C c) {}
			catch(E* e) {}
			catch(...)
			{
				return 5;
			}
			return 0;
		}
	//======================  end of sample.cpp  ==========================
                
]]>При каких значении argc программа вернёт значение 5?
Ответ:

 (1)

 (2)

 (3)

 (4)


Упражнение 9:
Номер 1
Какие утверждения о структурной безопасности ПО верны?

Ответ:

 (1) структурная безопасность достигается обязательным отказом от использования исключений 

 (2) структурная безопасность требует большой аккуратности при написании кода приложения 

 (3) для достижения структурной безопасности важна разработка безопасной архитектуры 

 (4) структурная безопасность позволяет не бояться ошибок имплементации объявленных интерфейсов 


Номер 2
Какие утверждения про безопасные функции и классы верны?

Ответ:

 (1) метод класса безопасен тогда, когда список бросаемых им исключений соответствует списку исключений в спецификации метода 

 (2) класс безопасен тогда, когда безопасны все его методы 

 (3) функция безопасна тогда, когда все бросаемые внутри её исключения внутри этой функции и обрабатываются  

 (4) для написания безопасных классов необходимо запретить пользоваться исключениями 


Номер 3

	//====================== start of sample.cpp ==========================
		struct A {};
		struct B {};
		struct C {};
		struct D {};
		struct E {};
		struct F {};
		
		class BaseIO
		{
		public:
			virtual int state() throw(A) = 0;
			virtual void read() throw(A, B) = 0;
			virtual void write() throw (C, D) = 0;
			virtual void open() throw (E,F) = 0;
			virtual void close() throw() = 0;
		};
		
		class DiskIO: public BaseIO
		{
		public:
			virtual int state() throw();
			virtual void read() throw (A, B);
			virtual void write() throw (C);
			virtual void open() throw (A, E);
			virtual void close() throw (F);
		};
	//======================  end of sample.cpp  ==========================
                
]]>Перегрузка каких виртуальных методов базового класса в классе DiskIO выполнена корректно?
Ответ:

 (1) state() 

 (2) read() 

 (3) write() 

 (4) open() 

 (5) close() 


Упражнение 10:
Номер 1
Какие методы класса не должны бросать исключения наружу?

Ответ:

 (1) конструкторы 

 (2) деструкторы 

 (3) константные методы 

 (4) безопасные методы 

 (5) статические методы 


Номер 2
Какие утверждения про корректное поведение при удалении объекта и освобождении ресурсов верны?

Ответ:

 (1) деструкторам запрещено выбрасывать исключения наружу 

 (2) внутри деструктора запрещено использовать исключения 

 (3) операции, которые могут бросить исключения или завершиться неудачей рекомендуется убрать из деструктора в отдельную функцию 

 (4) исключения, бросаемые при удалении вложенных объектов класса необходимо пробрасывать наружу без обработки 


Номер 3
Нейтральный код (функция или метод класса) должны:

Ответ:

 (1) при попадании в блок catch исключения, брошенного вложенным объектом, повторно бросать это исключение 

 (2) не допускать что бы наружу бросались любые исключения 

 (3) пробрасывать наружу исключения, брошенные из вложенных объектов 

 (4) обрабатывать исключения, бросаемые кодом самой функции или метода 

 (5) обрабатывать исключения, бросаемые вложенными объектами 


Упражнение 11:
Номер 1
Какие утверждения про стандартные исключения верны?

Ответ:

 (1) стандартная библиотека исключений содержит несколько независимых иерархий классов исключений 

 (2) иерархия исключений, используемая в разрабатываемом ПО должна быть основана на исключениях стандартной библиотеки 

 (3) все классы исключений из стандартной библиотеки являются производными от std::exceptiоn 

 (4) классы исключений из стандартной библиотеки являются безопасными 


Номер 2
Почему лучше использовать исключения, унаследованные от стандартных исключений?

Ответ:

 (1) классы исключения из стандартной библиотеки используются объектами и функциями стандартной библиотеки 

 (2) иерархию исключения стандартной библиотеки можно без больших усилий использовать в своих программах 

 (3) стандартные исключения могут быть использованы и обработаны в любой распространяемой библиотеке классов 

 (4) только исключения, унаследованные от классов стандартной библиотеки, могут быть безопасны 


Номер 3
Какой главный вопрос относительно исключений стандартной библиотеки необходимо решить при разработке своего программного продукта?

Ответ:

 (1) как будут использоваться атрибуты классов-исключений стандартной библиотеки 

 (2) какие исключения стандартной библиотеки будут использоваться 

 (3) какие исключения в каких случаях будут использоваться 

 (4) будет ли корневой класс иерархии исключений иметь отношение к исключениям стандартной библиотеки (унаследован или использован без наследования) 




Главная / Программирование / Программирование на С/С++ / Тест 94