воскресенье, 8 августа 2010 г.

QT интернационализация.

Хорошие статьи о создании поддержки нескольких языков в приложении.
1. Qt — трудности перевода
2. Локализация и числительные

суббота, 7 августа 2010 г.

QT. Цвета виджета.

QPalette p = MyLabel->palette();
p.setColor(QPalette::Window, Qt::black); //фон
p.setColor(QPalette::WindowText, Qt::red); //шрифт
MyLabel->setWidget(p);


все.

пятница, 6 августа 2010 г.

QT. QObject. Первые ошибки. Collect2: ld returned 1 exit status.

В связи со срочностью написания приложения на QT, была бегло пролистана соответствующая книжка. За эту спешку поплатился кучей глупых ошибок. Решил собрать коллекцию таких, на которые MinGW невразумительно ругается :)

При работе с QObject, очень просто получить такое:
1. no matching function for call to 'QObject::connect(...)'
2. undefined reference to 'vtable for MyClass'
3. collect2: ld returned 1 exit status

Последняя ошибка на первом месте моего хит-парада неприятных ошибок :)

Итак, если мы хотим использовать объект QObject, нужно не забывать:

  • Определять классы, использующие макрос Q_OBJECT в заголовочном файле (а не cpp). Иначе схлопочем ошибки 1 и 3.
  • Вставлять макроса Q_OBJECT (Ошибка 1). Примечание: если собрать проект без этого макроса, потом вставить его и опять попробовать собрать, то можно получить ошибки 2 и 3. Нужно произвести чистку проекта (или тупо грохнуть папку с билдом. В QT Creator она по умолчанию-MyProject-build-desktop)
  • Наследоваться от QObject, или его производного класса (Ошибка 1).
  • Вставлять #include . Ошибки можно и не получить, но сигналы и слоты работать не будут.
  • Определять объявленные слоты, если не хотим получить ошибку 3. С этим я конкретно намучался. "collect2: ld returned 1 exit status" и все! Ну как тут понять, что я просто забыл написать тело для слота MyClass::mySlot(){/* */}


UPD (7.08.10 18:25):
Блин, мне было нужно смотреть консоль сборки (QT Creator). Я бы сразу увидел дополнительную информацию о причинах ошибки.

среда, 7 июля 2010 г.

Еще 2 теста на Quizful

Я просто был обязан их пройти :)

Pascal - Основы:
Правильных ответов: 13 / 16 (81 %) требуется: 12
Синтаксис 3 / 4 (75 %)
Управляющие конструкции 3 / 4 (75 %)
Процедуры и функции 2 / 3 (66 %)
Указатели и ссылки 1 / 1 (100 %)
Типы данных 4 / 4 (100 %)

Delphi 7 - Основы
Правильных ответов: 14 / 18 (77 %) требуется: 14
Синтаксис 4 / 4 (100 %)
Ход выполнения программы 2 / 3 (66 %)
Указатели и ссылки 2 / 3 (66 %)
Массивы 2 / 3 (66 %)
Классы и объекты 3 / 4 (75 %)
Остальные 1 / 1 (100 %)

Радует, что провалов нет.

понедельник, 5 июля 2010 г.

"Это же БИБЛИЯ))) Не продам..."

Таким был один из комментариев в местном сообществе, на мое предложение купить бумажную книгу Страуструпа :) Ее нигде нет. В Ozon'е, Books.ru, Bolero и в куче других нет. В электронном виде не интересно.

воскресенье, 4 июля 2010 г.

Сервис онлайн тестирования Quizful

Про этот сервис я знал уже давно, если не ошибаюсь, прочитал про него на Хабре. После прочтения заглянул на него, ради интереса прошел какой-то тест. И только потому, что саморазвиваться мне не очень хотелось, я долго не возвращался туда. Но когда захотел проверить свои знания c++, сразу же вспомнил о нем. Итак, описание с сайта Quizful.net:

Проект Quizful предназначен для онлайн-тестирования специалистов в сфере информационных технологий. Quizful является community-driven сервисом и развивается во многом благодаря усилиям сообщества ИТ-специалистов.

Цель проекта - предоставить качественный бесплатный сервис, который бы не только проверял уровень имеющихся знаний, но и помогал в получении новых знаний.


То, что нужно. Сразу был выбран тест "C++ - Основы". И вот горькая правда: тест не пройден.

Правильных ответов: 11 / 20 (55 %) требуется: 15
Базовые понятия 2 / 5 (40 %)
Управляющие конструкции 3 / 3 (100 %)
Функции 2 / 3 (66 %)
Ссылки и указатели 3 / 3 (100 %)
Структуры и классы 0 / 4 (0 %)
Массивы 1 / 2 (50 %)

Я конечно очень расстроился, но комменты приободрили:

Отличный тест на знание C++! Я его 2 раза завалил - прошел только с 3-ей попытки, хотя программирую на нем уже 8 лет! После теста возникает непреодолимое желание схватить книгу Страуструпа и читать до посинения! Жаль что времени на это у меня нет и не предвидится :( А так Автору теста - 5!

До прохождения теста считал себя если не крутым, то неплохим знатоком С++, благо кодирую на нем уже года три, есть несколько завершенных проектов... но тест оказался "ушатом холодной воды" выявил кучу моих пробелов в теории - пройти его сумел только с 4го раза. Почувствовал себя невеждой. Срочно открыл книги Кернигана, Страуструпа и Майерса - сидеть мне с ними по вечерам месяц, пока не пройду без ошибок все тесты.

Значит все не так уж плохо. И не зря я долбил указатели, 3/3 - порадовало :)

Обычно я не люблю тесты за их требования знать половину справочника, то, что я за полторы секунды найду в гугле. Тут же, видимо благодаря сообществу, вопросы в целом понравились. То, с чем мы сталкиваемся на практике.

Например: Что будет выведено на экран после выполнение данного фрагмента кода?
int x = 0;
int y = 0;

if (x++ && y++){
y += 2;
}

cout << x + y;


Не буду писать (но очень хочется, так как из-за этого я ответил неверно), что есть подвох - в программировании все строго.

Варианты ответа:
0 (84 / 368)
1 (77 / 368)
2 (103 / 368)
3 (12 / 368)
4 (91 / 368)
В скобках количество давших такой ответ и это самое любопытное :)

пятница, 1 января 2010 г.

Планы

Первый день нового года - отличный повод строить планы.

Для работы:
· В первую очередь (в первых месяцах), хотелось бы занятся изучением процесса разработки ПО.
· Администрирование Windows Server
· Нужно более хорошее знание Oracle, pl/sql.
· Основы информационной безопасности.

Для себя
· Основы Linux
· Основы Adobe Flash (просто интересно)

В конце года можно будет подвести итоги :D

четверг, 1 октября 2009 г.

Функция без явного определения

Убойный для меня пример.
typedef int (*pf)(int, int);
char c[] = {85,-119,-27,-117,69,12,3,69,8,93,-61,-112};
pf sum = (pf)c; //reinterpret_cast отказывается, поэтому так.
cout << sum(2,3); //Вывод 5.


* This source code was highlighted with Source Code Highlighter.
Теперь sum - функция сложения, являющаяся аналогом этой:
int sum(int a, int b){return a+b;}

Сначала я написал нормальную функцию sum, затем байт за байтом просмотрел ее содержимое в памяти. К сожалению sizeof к функциям неприменим, поэтому я, после sum, определил еще одну функцию, и предположил, что в памяти они тоже рядом. Их адреса различались на 12 байт.

UPD: Одной строкой:
cout << ((int (*)(int, int))"\x55\x89\xE5\x8B\x45\x0C\x03\x45\x08\x5D\xC3\x90")(2,3);

Функции

Страуструп говорит, что с функцией можно сделать только две вещи, это вызвать ее и получить ее адрес. Я добавлю, для ясности, что этот адрес можно присвоить указателю на функцию и вызвать функцию с помощью этого указателя. Эти указатели не представляют собой что-то новое, они хранят адрес функции.

Повторюсь, что я веду этот блог не как учебное пособие, а пытаюсь объяснить самому себе сложные моменты (написание топика заставляет достаточно подробно вникнуть в суть), а так же необычные вещи удивившие меня. Еще я люблю очень маленькие(особенно в одну строчку :), но показательные примеры.

Вопрос которым я задался: можно ли вызвать функцию, имея только ее адрес хранящийся в long. Разумеется просто ради интереса, без практической пользы. Без reinterpret_cast обойтись явно не смогу. Еще понадобится тип функции.


char f(){return 'f';}

typedef char (*PF)(); //именно такой тип у f()

long a = reinterpret_cast<long>(f); //получаем число...
cout << (reinterpret_cast<PF>(a))(); //... говорим, что это число - указатель на функцию. Скобки () приводят вызову функции.
 

суббота, 26 сентября 2009 г.

Константы

У Эккеля не зря целая глава выделена под константы. В этой теме много интересного. Сейчас я хочу создать константу и подкопаться к ней через указатели.

const int a = 1;
int b;
cout << &a << &b; //У меня, при запусках, b всегда имеет адрес меньше(на 4 байта), чем a.
int* p = (&b+1); //Это адрес константы a
cout << *p //1
*p = 2; //Меняем
cout << a << endl << *p; //1 2


Вроде поменяли, однако a осталось прежним, но по ее адресу лежит число 2. Дело в том, что компилятор просто заменяет все вхождения a на 1, и обычно для этого не выделяет память. Но когда мы написали &a, компилятор все-таки выделил память для нее и записал туда значение. Но все-равно перед компиляцией заменил в коде a на 1. Память вроде бы пропадает впустую, ее даже можно изменить.