Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt]Перегрузка оператора 
:(
    Опции темы
aspirin2003
Дата 21.7.2008, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.3.2007
Где: Саратов

Репутация: нет
Всего: нет



Извиняюсь что не совсем в тему, но все же...
В общем создаю класс, наследуя его от QObject, например:
Код

#ifndef CALCELEMENT_H
#define CALCELEMENT_H

#include <QObject>
#include <QStringList>

class CalcElement : public QObject
{
    Q_OBJECT

public:
    CalcElement(QObject *parent);
    ~CalcElement();
    CalcElement operator + (CalcElement &m1);

private:
    double dd;
    
};

#endif // CALCELEMENT_H

Код

#include "calcelement.h"

CalcElement::CalcElement(QObject *parent)
    : QObject(parent)
{
    this->dd = 100;
}

CalcElement::~CalcElement()
{

}

CalcElement CalcElement::operator +(CalcElement &m1)
{
    CalcElement res(NULL);
    res.dd = dd + m1.dd;
    return res;
}

и пытаюсь перегрузить в нем оператор '+'

Проверяю так:
Код

    CalcElement elem(NULL);
    CalcElement elem1(NULL);
    CalcElement elem2 = elem + elem1;


Но выскакивает ошибка:
error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'

Если же не наследоваться от QObject, то все ok. 


PM MAIL   Вверх
anatox91
Дата 21.7.2008, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: нет
Всего: 13



Цитата(aspirin2003 @  21.7.2008,  10:14 Найти цитируемый пост)
res.dd = dd + m1.dd;

у тебя же dd - private


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
aspirin2003
Дата 21.7.2008, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.3.2007
Где: Саратов

Репутация: нет
Всего: нет



Цитата(anatox91 @ 21.7.2008,  10:18)
Цитата(aspirin2003 @  21.7.2008,  10:14 Найти цитируемый пост)
res.dd = dd + m1.dd;

у тебя же dd - private

Ну и что? dd используется внутри класса CalcElement, и доступен его методам. Дело не в этом, я думаю
P.S. На всякий случай проверил, сделал public - ничего не изменилось
PM MAIL   Вверх
anatox91
Дата 21.7.2008, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: нет
Всего: 13



aspirin2003, тю блин, сорри, забыл что это мембер


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
SABROG
Дата 21.7.2008, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Попробуй использовать вместо dd другое имя, обычно имена и dd используются в приватных классах Qt. Попробуй так изменить:

Код

res.dd = CalcElement::dd + m1.dd;



--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
anatox91
Дата 21.7.2008, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: нет
Всего: 13



*deleted*

Это сообщение отредактировал(а) anatox91 - 21.7.2008, 11:21


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
SABROG
Дата 21.7.2008, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Цитата(anatox91 @ 21.7.2008,  11:20)
*deleted*

Да нет, только [] и то где-то в QObjectPrivate.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
aspirin2003
Дата 21.7.2008, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.3.2007
Где: Саратов

Репутация: нет
Всего: нет



Цитата(SABROG @ 21.7.2008,  11:19)
Попробуй использовать вместо dd другое имя, обычно имена и dd используются в приватных классах Qt. Попробуй так изменить:

Код

res.dd = CalcElement::dd + m1.dd;

Нет, эта строка вообще не влияет на ошибку. Даже если ее закомментировать и возвращать NULL, то ничего не меняется.
Насколько я понял, ошибка возникает здесь: 
Код

   CalcElement res(NULL);


P.S. На всякий случай изменять имя на другое пробовал, не помогает

Это сообщение отредактировал(а) aspirin2003 - 21.7.2008, 11:42
PM MAIL   Вверх
SABROG
Дата 21.7.2008, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



В общем дело обстоит так. Конструктор копирования у классов на базе QObject переопределен таким образом, чтобы запретить эту операцию. Существует макрос Q_DISABLE_COPY:

Код

#if !defined(Q_NO_DECLARED_NOT_DEFINED) || !defined(QT_MAKEDLL)
 #define Q_DISABLE_COPY(Class) \
     Class(const Class &); \
     Class &operator=(const Class &);
#else
 #define Q_DISABLE_COPY(Class)
#endif


Который прописан в секции private QObject'a:

Код

protected:
    QObjectData *d_ptr;

    static const QMetaObject staticQtMetaObject;

    friend struct QMetaObject;
    friend class QApplication;
    friend class QApplicationPrivate;
    friend class QCoreApplication;
    friend class QCoreApplicationPrivate;
    friend class QWidget;
    friend class QThreadData;

private:
    Q_DISABLE_COPY(QObject)
    Q_PRIVATE_SLOT(d_func(), void _q_reregisterTimers(void *))
};



Может быть возможно переопределить конструктор копирования в своем классе и оператор =, но не известно к чему это может привести.

Это сообщение отредактировал(а) SABROG - 21.7.2008, 12:12


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
aspirin2003
Дата 21.7.2008, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.3.2007
Где: Саратов

Репутация: нет
Всего: нет



Цитата(SABROG @ 21.7.2008,  12:08)
Может быть возможно переопределить конструктор копирования в своем классе и оператор =, но не известно к чему это может привести.

Моих знаний по C++ врядли хватит чтобы самому с этим разобраться :(
Возможно ли решить проблему другим способом? Ведь перегрузка операторов в классе - достаточно распространенное явление

P.S. Сделал так:
Код

CalcElement::CalcElement(const CalcElement& c_el)
{
    dd = c_el.dd;
}


Теперь вроде работает, но прочитал в одной статейке, что "...Переопределение конструктора копирования является чрезвычайно ответственным поступком. Явное определение конструктора копирования вызывает изменения в работе программы..."

Теперь еще вопрос - надо ли в конструкторе копирования что-либо делать с методами класса, или делать только копирование его полей?

Это сообщение отредактировал(а) aspirin2003 - 21.7.2008, 13:27
PM MAIL   Вверх
SABROG
Дата 21.7.2008, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



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

Кстати интересно возможно ли вызвать дефолтный конструктор копирования ?:

Код

CalcElement::CalcElement(const CalcElement& c_el)
{
    CalcElement::CalcElement(c_el);
}


Или возникнет рекурсия ?

А вообще конструкторов 2:

CalcElement::CalcElement(const CalcElement& c_el)
CalcElement::CalcElement(CalcElement& c_el)



--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
aspirin2003
Дата 21.7.2008, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.3.2007
Где: Саратов

Репутация: нет
Всего: нет



Цитата(SABROG @ 21.7.2008,  13:42)
Кстати интересно возможно ли вызвать дефолтный конструктор копирования ?:

Код

CalcElement::CalcElement(const CalcElement& c_el)
{
    CalcElement::CalcElement(c_el);
}


Или возникнет рекурсия ?

Не знаю насчет рекурсии, но Access violation точно возникает
PM MAIL   Вверх
SABROG
Дата 21.7.2008, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Потому что стек заканчивается на возврат. Т.е. рекурсия идет.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
aspirin2003
Дата 21.7.2008, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.3.2007
Где: Саратов

Репутация: нет
Всего: нет



Всем спасибо за ответы, особенно SABROG
PM MAIL   Вверх
aspirin2003
Дата 24.7.2008, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.3.2007
Где: Саратов

Репутация: нет
Всего: нет



Теперь в коде:
Код

CalcElement res(NULL);
CalcElement item_1(NULL);
CalcElement item_2(NULL);
...
res = item_1 + item_2;

 вылазит ошибка
error C2248: 'QObject::operator =' : cannot access private member declared in class 'QObject'
Насколько я понял теперь еще нужно переопределить оператор '='.  Как это лучше сделать - копированием полей как в конструкторе копирования, или есть какой-то более оптимальный способ, чтобы не тратить время на перемещение данных в памяти?

P.S. Тем более как выяснилось, простое копирование полей не прокатывает :(
Делаю:
Код

CalcElement CalcElement::operator =(CalcElement &m1)
{
    CalcElement res(NULL);
    res.mask = m1.mask;
    res.tuple = m1.tuple;
    res.maskLen = m1.maskLen;
    res.tupleLen = m1.tupleLen;
    return res;
}


В res вроде все как надо, а возвращаемый на самом деле объект в полях содержит какую-то чушь.
Скорее всего надо как-то по-другому делать, а как именно я не знаю. Помогите пожалуйста!

Это сообщение отредактировал(а) aspirin2003 - 24.7.2008, 09:59
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.1523 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.