Квітень 28th, 2009
Життя підкинуло цікаву ідею для перевірки практичних навичок C++ програміста. Таке собі тестове завдання.
Нижче наведено клас — зв’язаний список, призначений для зберігання всяких різних об’єктів. Клас поганий, нормальний С++ програміст такого собі дозволяти не повинен. Як ви гадаєте, що саме недобре у цьому класі?
-
class Linked_Lists
-
{
-
public:
-
Linked_Lists();
-
~Linked_Lists();
-
bool add(void *data);
-
bool remove_head();
-
bool first();
-
bool last();
-
bool next();
-
bool prev();
-
void* get_data();
-
bool is_empty();
-
int get_count();
-
-
protected:
-
struct Node
-
{
-
void *data;
-
Node *prev_node;
-
Node *next_node;
-
};
-
Node *head;
-
Node *tail;
-
Node *current;
-
int count;
-
};
Слід сказати, тут дещо специфічний дизайн, так уже сталося. Елементи додаються та видаляються зі списку за принципом FIFO. Водночас, доступний вказівник, який можна туди-сюди пересувати по списку, щоб отримати доступ до будь-яких даних. Втім, це не суттєво. Припустимо, так було потрібно для чогось.
Справжній недолік цього класу в іншому. У якості підказки варто глянемо на реалізацію деструктора:
-
Linked_Lists::~Linked_Lists()
-
{
-
Node *node;
-
-
if (head == 0) return;
-
-
first();
-
do
-
{
-
node = current;
-
next();
-
delete node->data;
-
delete node;
-
} while (current != 0);
-
}
Що ж саме у ньому не так? (ще…)
Категорії: C/C++ |
Теґи:c/c++, програмування | Кометарів немає
Лютий 25th, 2009
В принципі, це й так всі нормальні люди знають, але хай буде у якості нотаток на випадок раптового удару граблями приступу склерозу
Так от, відомо, що у C булівський тип відсутній. Можна використовувати такого шось типу
-
#ifndef __cplusplus
-
-
#ifndef bool
-
typedef char bool;
-
#endif
-
-
#ifndef true
-
#define true ((bool) 1)
-
#endif
-
-
#ifndef false
-
#define false ((bool) 0)
-
#endif
-
-
#endif /* not C++ */
Але всі велосипеди було вже давно винайдено й стандартизовано. Слово українській вікіпедії:
stdbool.h — заголовний файл стандартної бібліотеки мови програмування С, котрий містить чотири макроси для роботи з типом даних bool. Даний заголовний файл з’явився у стандартні C99.
Визначення макросів згідно стандарту IEEE Std 1003.1-2001:
- bool котрий розширюється до _Bool
- true котрий розширюється до 1
- false котрий розширюється до 0
- __bool_true_false_are_defined котрий розширюється до 1
Категорії: C/C++ |
Теґи:bool, c/c++, stdbool.h | Кометарів немає
Січень 14th, 2009
У QT знайшов черговий приклад, як не треба робити. Спішу поділитися
Уявіть собі, є якийсь там клас QPluginLoader, який має метод QString QPluginLoader::errorString (). Типу, якщо шось там спрацювало не так як треба, то цей метод повертатиме текстовий опис помилки. Питання на засипку: що видає ця функція, якщо все пройшло добре? Коли б це проектували нормальні люди, то відповідь була б “No error”, або щось подібне. Стандартна perror(), наприклад, в такому випадку чітко і ясно пише “Success” (в англійській локалі, звісно). Натомість витвір заморожених норвежців запросто видає “Unknown error”. А фіглі його тут зайвий раз викликають…
Категорії: C/C++, Життя |
Теґи:c/c++, QT, програмування | Кометарів немає
Січень 12th, 2009
Вирішив викласти у себе, може, комусь знадобиться
стандарт C (C99)
чинний на сьогоднішній день стандарт C++
Категорії: C/C++, Життя, програмування |
Теґи:c/c++, стандарти | Кометарів немає
Листопад 10th, 2008
Ще одне цікаве завдання, з тих, що пропонує Яндекс:
Есть класс 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;
-
}
-
Исходя из предположения, что количество языков будет добавляться, предложите refactoring кода. Аргументируйте преимущество вашего кода над существующим.
(ще…)
Категорії: C/C++, Паттерни проектування |
Теґи:c/c++, factory, refactoring, yandex, паттерни програмування, програмування, рефакторінг | Кометарів немає
Листопад 7th, 2008
Виявляється, Яндекс постійно набирає нових людей, зокрема, розробників C++. Перша частина співбесіди — онлайн. Завдання, що там пропонуються, без сумніву, варті уваги. Ось , наприклад, таке
-
-
class Top {
-
public:
-
virtual ~Top (){}
-
};
-
-
class Right : virtual public Top {
-
public:
-
void f () {}
-
};
-
-
class Left : virtual public Top {
-
public:
-
void f () {}
-
};
-
-
class Bottom : public Right, public Left {
-
public:
-
/*
-
* что надо написать чтобы выполнялось требование описанное в main
-
*/
-
};
-
-
int main (int, char**) {
-
Bottom b;
-
b.f(); // Требование: вызов Left::f()
-
}
-
Звісно, перше, що спадає на думку, зробити шось типу
void f () { Left::f();}
Але так негарно. Виклик однієї функції через іншу… Не дуже добре, особливо якщо в реальному житті трапиться метод з багатьма параметрами.
Насправді, розумні люди підказали , треба робити так:
using Left::f;
Цей запис виглядав би так само, навіть якби у батьківських класах метод f приймав би якісь параметри.
В тому коді є ще пара цікавих моменти, про які особисто я не знав, не знав, та й забув.
По-перше, спосіб наслідування virtual publiс. Виявляється, слово virtual в даному випадку означає, що у класі Bottom буде присутня одна і тільки одна реалізація об’єкту класу Top. Якби virtual не було, тоді виникала б неоднозначність при використанні членів класу Top, успадкованих як в Left, так і в Right. Втім, в прикладі цього не видно, бо в Top занадто спрощений.
По-друге, клас Top має віртуальний деструктор. Питання: який взагалі сенс деструктору бути віртуальним, коли його все одно не можна перекрити в класі-нащадку? Погугливши, знайшов відповідь . Справа в тому, що якби не слово virtual, то ось в такому випадку
int main {
Top* tp = new Right;
}
було б викликано деструктор явно заданого класу (Top), в той час, коли насправді треба викликати ~Right.
Категорії: C/C++ |
Теґи:c/c++, virtual, yandex, Яндекс | Кометарів немає
Вересень 30th, 2008
C++ відомий своєю заплутаністю. Ключових слів ніби й небагато, але кожне може бути використане у багатьх контекстах. В цьому дописі я спробую звести воєдино всі відомі мені способи використання слова static. Хто знає, може буде щось таке, чого ви не знали раніше
(ще…)
Категорії: C/C++ |
Теґи:c/c++, keyword, static | Кометарів немає
Вересень 13th, 2008
Еліпсисом (англ ellipsis) називають елемент синтаксису мови C, що представляє собою три крапки. Наприклад, як у оголошенні фукнції printf :
int printf(const char *format, ...);
Еліпсис означає, що на цьому місці знаходится якась кількість змінних якогось типу. Функція сама має визначити, які саме змінні їй передали.
(ще…)
Категорії: C/C++ |
Теґи:c/c++, ellipsis, printf, va_args, еліпсис | Коментарів: 1
Серпень 28th, 2008
Я до цього часу вважав, що C++ є розширенням C. Ну, насправді, я розумію, що це абсолютно різні мови, з різними сферами застосування і т.д. і блаблабла… Але от була така впевненість, що формально нема в C нічого такого, чого б не було C++. Тобто, я вважав, що сертифікований компілятор C++ має без будь-яких зауважень скомпілювати C-програму. А от ні, виявляється, є одна штука, якою ці мови відрізняються. Хоча, звісно, це така, дуже теоретична відмінність, наврядчи хтось може з цим зіткнутися в реальному житті.
(ще…)
Категорії: C/C++ |
Теґи:c/c++, gcc, програмування | Кометарів немає
Липень 16th, 2008
Використання консольного GCC – страшний нічний кошмар для новачків, що звикли до зручних графічних середовищ програмування у Windows. Величезна кількість опцій командного рядка лякає навіть відчайдухів, які відкривають man в надії знайти рішення проблеми. В цій замітці я коротко опишу найцікавіші опції GCC, про які варто знати усім. (ще…)
Категорії: C/C++ |
Теґи:c/c++, gcc, програмування | Коментарів: 1