Russian Qt Forum
Ноябрь 23, 2024, 14:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Помощь в разборе примера, создание класса.  (Прочитано 11170 раз)
Gate007
Гость
« : Июль 12, 2011, 16:32 »

В книге
Макс Шлее - QT Профессиональное программирование на C++
есть следующий пример:
Код
C++ (Qt)
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(bool readonly READ isReadOnly WRITE setReadOnly)
private:
 
bool m_bReadOnly;
public:
MyClass(QObject* pobj = 0) : QObject(pobj)
  , m_bReadOnly(false)
{
}
 
public:
void setReadOnly(bool bReadOnly)
{
m_bReadOnly = bReadOnly;
}
bool isReadOnly() const
{
return m_bReadOnly;
}
}
Вопрос 1:
что делается в строке
Код:
MyClass(QObject* pobj = 0) : QObject(pobj)
   , m_bReadOnly(false)
{
}
Я понимаю что это конструктор, но все явно глубже.
Вопрос 2.
Чуть ниже написано:

Цитировать
Из программы мы можем изменить значение нашего свойства следующим
образом:
pobj->setProperty(„ReadOnly", true);
Или получить текущее значение:
bool bReadOnly = pobj->property("ReadOnly").toBool();

С изменением значения все ясно, а вот с получением... Почему не использована функция isReadOnly()? Я думал что в QT как раз используют методы для получения и изменения полей, а здесь получается что просто обращаются к полю.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Июль 12, 2011, 16:38 »

В данном случае можно использовать оба способа. Шлее показывает применение макроса Q_PROPERTY.

П.С. можешь этим не пользоваться. Улыбающийся
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #2 : Июль 12, 2011, 17:18 »

1. это просто конструктор. в нем вызывается конструктор базового класса QObject(pobj) и переменной m_bReadOnly присваивается значение false
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Июль 12, 2011, 17:23 »

Я понимаю что это конструктор, но все явно глубже.
Не надо впадать в крайности (типа "ой как глубоко" или наоборот "та это все фуфло!"). Надо разобраться и иметь свое мнение (это всегда непросто)
С изменением значения все ясно, а вот с получением... Почему не использована функция isReadOnly()? Я думал что в QT как раз используют методы для получения и изменения полей, а здесь получается что просто обращаются к полю.
Ну как это "автор следует собственным рекомендациям"? Они ведь написаны для других Улыбающийся
П.С. можешь этим не пользоваться. Улыбающийся
Пока робко но прогресс налицо - рад за Вас  Улыбающийся
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Июль 13, 2011, 08:06 »

>>Почему не использована функция isReadOnly()?
тут всё просто, Шлее привёл методы чтения и записи свойств (не просто полей класса!!), а именно свойств объектов Qt, которые объявляются при помощи макроса Q_PROPERTY.
С помощью методов setProperty и property можно обращаться к любым свойствам наследников QObject.

Но ещё раз обращаю внимание, не все поля класса являются свойствами, а только те, который объявлены с помощью макроса Q_PROPERTY
Записан

Юра.
Gate007
Гость
« Ответ #5 : Июль 13, 2011, 10:58 »

Если можно, "по слогам", что тут делается?
Код:
MyClass(QObject* pobj = 0) : QObject(pobj)
  , m_bReadOnly(false)
{
}
Это конструктор, понимаю.
Код:
MyClass(QObject* pobj = 0)
Не понимаю
Код:
MyClass(QObject* pobj = 0) : QObject(pobj)
Тоже не понимаю
Код:
 , m_bReadOnly(false) 
Атрибут  m_bReadOnly инициализируется false.
Код:
{
}
Пустое тело конструктора.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #6 : Июль 13, 2011, 11:05 »

QObject* pobj = 0 - параметр конструктора (его можно не указывать, тогда он будет равен 0).
: QObject(pobj) - вызываем конструктор родителя.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #7 : Июль 13, 2011, 12:11 »

>>Это конструктор
а конструктор - функция, только не возвращающая ничего (как void), только ради отличия у него нет вообще возвращаемого значения. А раз уж функция, то должны быть скобки, они есть. Но ещё есть и входные аргументы (как указал LisandreL).

>>: QObject(pobj) - вызываем конструктор родителя.
лучше слово родитель заменить на "базовый класс", т.к. в рамках Qt может возникнуть путаница с родственными связями объектов.

конструктор базового класса вызываем, т.к. его тоже надо инициализировать, в нём ведь тоже есть некоторые данные. Если мы явно не вызываем конструктор базового класса, то компилятор это сделает за нас, но он вызовет только конструктор по умолчанию. Нам это не подходит, т.к. мы хотим передать указатель на родительский объект.

>>Атрибут  m_bReadOnly инициализируется false.
только обрати внимание, что выделенное жирным
MyClass(QObject* pobj = 0) : QObject(pobj), m_bReadOnly(false)
называется строка инициализации (если я не путаю) и в ней участвуют только конструкторы.
Т.е.
m_bReadOnly(false) - вызов конструктора объекта m_bReadOnly, с аргументом false.

Для того чтобы переменную инициализировать при объявлении, в Си мы писали так:
bool myvar = true;
В Си++ принято использовать конструктор типа, т.е. так:
bool myvar(true);

А также в Си++ приведение типа принято делать через конструктор:
Си
char mychar = 0x12;
int myint = (int) mychar;

Си++
char mychar(0x12);
int myint = int(mychar); // вызов конструктора типа int c аргументом типа char
« Последнее редактирование: Июль 13, 2011, 12:18 от lit-uriy » Записан

Юра.
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #8 : Июль 13, 2011, 12:23 »

>>Атрибут  m_bReadOnly инициализируется false.
только обрати внимание, что выделенное жирным
MyClass(QObject* pobj = 0) : QObject(pobj), m_bReadOnly(false)
называется строка инициализации (если я не путаю) и в ней участвуют только конструкторы.
Т.е.
m_bReadOnly(false) - вызов конструктора объекта m_bReadOnly, с аргументом false.

Для того чтобы переменную инициализировать при объявлении, в Си мы писали так:
bool myvar = true;
В Си++ принято использовать конструктор типа, т.е. так:
bool myvar(true);
Неверно. Если явно не указать MyClass(QObject* pobj = 0) : QObject(pobj), то QObject инициализируется дефолтом. Пример:
Код
C++ (Qt)
A::A ()
{
 SomeMember = 0;
}
 
Код
C++ (Qt)
A::A ()
: SomeMember (0)
{
 
}
 
Разница в том, что в первом варианте SomeMember сначала проинициализируется каким-то дефолтным значением, а потом ему будет присвоено значение, а во втором варианте все это делается за одно действие.

Цитировать
А также в Си++ приведение типа принято делать через конструктор:
Си
char mychar = 0x12;
int myint = (int) mychar;

Си++
char mychar(0x12);
int myint = int(mychar); // вызов конструктора типа int c аргументом типа char
Ни в коем случае. в С++ принято делать static_cast.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Июль 13, 2011, 12:44 »

что в первом варианте SomeMember сначала проинициализируется каким-то дефолтным значением, а потом ему будет присвоено значение,
Ничем он не проинициализируется, будет заполнен мусором - ну или как решит malloc или отладчик

Цитировать
int myint = (int) mychar;
...
int myint = int(mychar); // вызов конструктора типа int c аргументом типа char
Ни в коем случае. в С++ принято делать static_cast.
int "старше" (больше по размеру) и тоже знаковый, поэтому простая запись
Код
C++ (Qt)
int myint = mychar;
 
Со всех точек зрения  безопасна, и никакие ухищрения не нужны
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #10 : Июль 13, 2011, 12:52 »

>>Неверно. Если явно не указать
в твоей цитате про конструктор QObject речь не шла. Смотри мой пост, абзац выше.

>>Ни в коем случае. в С++ принято делать static_cast.
это уже из более сложной области. Суть моего примера, это уход от того что было принято в Си.
Записан

Юра.
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #11 : Июль 13, 2011, 13:48 »

что в первом варианте SomeMember сначала проинициализируется каким-то дефолтным значением, а потом ему будет присвоено значение,
Ничем он не проинициализируется, будет заполнен мусором - ну или как решит malloc или отладчик
Для простых типов - будет заполнен мусором, а вот если SomeMember - класс, то будет вызван его конструктор без параметров и выполнится заданная в нём инициализация.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Июль 13, 2011, 13:51 »

Для простых типов - будет заполнен мусором, а вот если SomeMember - класс, то будет вызван его конструктор без параметров и выполнится заданная в нём инициализация.
Совершенно верно - для POD типов никакой инициализации не выполняется
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.134 секунд. Запросов: 23.