Перечислите все проблемы, которые вы видите в данном коде: class Foo { public: Foo(int j) { i=new int[j]; } ~Foo() { delete i; } //Виртуальный деструктор класса позволит удалять потомков класса Foo через их предка private: int* i; }; class Bar: Foo //Наследование с модификатором доступа public позволит использовать поля и методы класса Foo (см. 23 строку) { public: Bar(int j) { i=new char[j]; } //Необходимо добавить “Foo(j)” в список инициализациии ~Bar() { delete i; } private: char* i; }; void main() //Предпочтительнее использовать int как тип возвращаемого значения функции main { Foo* f=new Foo(100); Foo* b=new Bar(200); (23 строка) *f=*b; delete f; delete b; //После реализации виртуального деструктора нет необходимости в данной инструкции } Есть класс CodeGenerator, который умеет генерить код на разных языках. Предложите рефакторинг с учетом, что количество языков будет расширяться class CodeGenerator { public: enum Lang {JAVA, C_PLUS_PLUS, PHP}; CodeGenerator(Lang language) { _language=language; } std::string generateCode() { switch(_language) { case JAVA: //return generated java code case C_PLUS_PLUS: //return generated C++ code case PHP: //return generated PHP code } throw new std::logic_error("Bad language"); } std::string someCodeRelatedThing() // used in generateCode() { switch(_language) { case JAVA: //return generated java-related stuff case C_PLUS_PLUS: //return generated C++-related stuff case PHP: //return generated PHP-related stuff } throw new std::logic_error("Bad language"); } private: Lang _language; } _____________________________________________________________________________ class Lang { public: Lang() {}; virtual string returnGeneratedCode(){}; virtual string returnSomething(){}; }; class CPP: public Lang{ public: string returnGeneratedCode() override {}; string returnSomething() override {} ; }; class Java: public Lang{ public: string returnGeneratedCode() override; }; class CodeGenerator { public: CodeGenerator(Lang language) { _language=language; } std::string generateCode() { return _language.returnGeneratedCode(); } std::string someCodeRelatedThing() // used in generateCode() { return _language.returnSomething(); } private: Lang _language; }; Идея реализации заключается в том, что основные принципы ООП (наследование и инкапсуляция, в частности) позволят избежать лишних инструкций выбора, заменив последние на соответствующие методы класса-родителя Все ли хорошо в этом коде? Файл legacy.c int values[3]; //Декларацию массива value с помощью ключевого слова extern необходимо производить здесь, а не ниже Файл modern.cpp #define LEGACY_SIZE 3 extern int *values; //Необходимо убрать «extern int *», но добавить размерность массива values[3] class MyBlah {...}; //Необходимо указать конструктор класса с типом принимаемого аргумента int values[3] class Adapter { public: Adapter() { for (int i = 0; i < LEGACY_SIZE; ++i) map_[values[i]] = new MyBlah (values[i]); } private: std::map<int, MyBlah *> map_; }; Что не так в этом коде? Перечислите, какие недостатки вы видите. Предложите свой вариант рефакторинга. #include <stdio.h> class Feature { public: enum FeatureType {eUnknown, eCircle, eTriangle, eSquare}; Feature() : type(eUnknown), points(0) { } ~Feature() { if (points) delete points; //Деструктор с условием, которое вызывает подозрения } bool isValid() { return type != eUnknown; } bool read(FILE* file) { if (fread(&type, sizeof(FeatureType), 1, file) != sizeof(FeatureType)) return false; short n = 0; switch (type) //Использование условного оператора приводит к излишнему повторению кода и сложности при его изменении { case eCircle: n = 3; break; //Не интуитивно понятная переменная n case eTriangle: n = 6; break; //Предпочтительнее использовать отдельный метод, общего класса Shape (напр.), в котором будут поля для координат вершин (в случае с треугольником и квадратом) и координат центра и длины радиуса для окружности, а так же методы по типу draw и read case eSquare: n = 8; break; default: type = eUnknown; return false; } points = new double[n]; if (!points) return false; return fread(&points, sizeof(double), n, file) == n*sizeof(double); } void draw() { switch (type) { case eCircle: drawCircle(points[0], points[1], points[2]); break; case eTriangle: drawPoligon(points, 6); break; case eSquare: drawPoligon(points, 8); break; } } protected: void drawCircle(double centerX, double centerY, double radius); void drawPoligon(double* points, int size); double* points; FeatureType type; }; int main(int argc, char* argv[]) { Feature feature; FILE* file = fopen("features.dat", "r"); feature.read(file); if (!feature.isValid()) return 1; return 0; } Имеем чистый C. Напишите generic функцию линейного поиска в массиве. И приведите пример использования вашей функции. int generic(int A[], int key) { for (i = 0; i < N; i++) if (A[i] == key) return i; return -1; } Данная функция может использоваться при поиске символа в последовательности (например, рандомно сгенерированном массиве переменных типа int) #include <iostream> #include <ctime> using namespace std; int i, N; int generic(int A[], int key) { for (i = 0; i < N; i++) if (A[i] == key) return i; return -1; } int main() { int key, A[1000]; srand(time(NULL)); cout << "Array Size (max1000): "; cin >> N; cout << "The desired element: "; cin >> key; cout << "Source array: "; for (i = 0; i < N; i++) { A[i] = rand() % 10; cout << A[i] << " "; } if (generic(A, key) == -1) cout << "\nElement not found"; else cout << "\nItem Number: " << generic(A, key) + 1; } Имеем чистый С. Напишите reusable API для работы со связным списком структур. Структуры могу быть разного типа, но в одном списке будут структуры одного типа. Приведите пример использования вашего API. Затрудняюсь ответить