Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [Qt]Перегрузка оператора |
Автор: aspirin2003 21.7.2008, 10:14 | ||||||
Извиняюсь что не совсем в тему, но все же... В общем создаю класс, наследуя его от QObject, например:
и пытаюсь перегрузить в нем оператор '+' Проверяю так:
Но выскакивает ошибка: error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject' Если же не наследоваться от QObject, то все ok. |
Автор: anatox91 21.7.2008, 10:18 |
у тебя же dd - private |
Автор: aspirin2003 21.7.2008, 11:07 | ||
Ну и что? dd используется внутри класса CalcElement, и доступен его методам. Дело не в этом, я думаю P.S. На всякий случай проверил, сделал public - ничего не изменилось |
Автор: anatox91 21.7.2008, 11:16 |
aspirin2003, тю блин, сорри, забыл что это мембер |
Автор: SABROG 21.7.2008, 11:19 | ||
Попробуй использовать вместо dd другое имя, обычно имена d и dd используются в приватных классах Qt. Попробуй так изменить:
|
Автор: anatox91 21.7.2008, 11:20 |
*deleted* |
Автор: SABROG 21.7.2008, 11:23 | ||
Да нет, только [] и то где-то в QObjectPrivate. |
Автор: aspirin2003 21.7.2008, 11:36 | ||||||
Нет, эта строка вообще не влияет на ошибку. Даже если ее закомментировать и возвращать NULL, то ничего не меняется. Насколько я понял, ошибка возникает здесь:
P.S. На всякий случай изменять имя на другое пробовал, не помогает |
Автор: SABROG 21.7.2008, 12:08 | ||||
В общем дело обстоит так. Конструктор копирования у классов на базе QObject переопределен таким образом, чтобы запретить эту операцию. Существует макрос Q_DISABLE_COPY:
Который прописан в секции private QObject'a:
Может быть возможно переопределить конструктор копирования в своем классе и оператор =, но не известно к чему это может привести. |
Автор: aspirin2003 21.7.2008, 12:55 | ||||
Моих знаний по C++ врядли хватит чтобы самому с этим разобраться :( Возможно ли решить проблему другим способом? Ведь перегрузка операторов в классе - достаточно распространенное явление P.S. Сделал так:
Теперь вроде работает, но прочитал в одной статейке, что "...Переопределение конструктора копирования является чрезвычайно ответственным поступком. Явное определение конструктора копирования вызывает изменения в работе программы..." Теперь еще вопрос - надо ли в конструкторе копирования что-либо делать с методами класса, или делать только копирование его полей? |
Автор: SABROG 21.7.2008, 13:42 | ||
Конструктор копирования, что идет по-умолчанию сам копирует поля с данными. К методам это никак не относится, код методов один для всех экземпляров класса один, если только это не шаблон класса, где под каждый тип генерятся методы. Кстати интересно возможно ли вызвать дефолтный конструктор копирования ?:
Или возникнет рекурсия ? А вообще конструкторов 2: CalcElement::CalcElement(const CalcElement& c_el) CalcElement::CalcElement(CalcElement& c_el) |
Автор: aspirin2003 21.7.2008, 14:23 | ||||
Не знаю насчет рекурсии, но Access violation точно возникает |
Автор: SABROG 21.7.2008, 14:27 |
Потому что стек заканчивается на возврат. Т.е. рекурсия идет. |
Автор: aspirin2003 21.7.2008, 16:13 |
Всем спасибо за ответы, особенно SABROG |
Автор: aspirin2003 24.7.2008, 09:04 | ||||
Теперь в коде:
вылазит ошибка error C2248: 'QObject::operator =' : cannot access private member declared in class 'QObject' Насколько я понял теперь еще нужно переопределить оператор '='. Как это лучше сделать - копированием полей как в конструкторе копирования, или есть какой-то более оптимальный способ, чтобы не тратить время на перемещение данных в памяти? P.S. Тем более как выяснилось, простое копирование полей не прокатывает :( Делаю:
В res вроде все как надо, а возвращаемый на самом деле объект в полях содержит какую-то чушь. Скорее всего надо как-то по-другому делать, а как именно я не знаю. Помогите пожалуйста! |
Автор: aspirin2003 24.7.2008, 16:36 | ||
В общем заработало когда переопределил так:
Однако мне кажется что это не лучший способ (данные перемещаются из одной области памяти в другую). Может есть какой-нибудь способ передачи по указателю/ссылке? |
Автор: SABROG 24.7.2008, 17:30 |
Т.е. если позволить компилятору присваивать данные за тебя, то перемещения данных из одной области памяти в другую не будет ;) ? Посмотри как в Qtшных классах реализован алгоритм "implicit sharing (copy-on-write)" и сделай также если хватит знаний. |
Автор: SABROG 24.7.2008, 20:13 |
Асистент вроде не находит. Нашел только QAtomicInt и QAtomicPointer, но пока не понял их предназначение. |
Автор: aspirin2003 25.7.2008, 08:59 | ||
Прочитал статью http://doc.trolltech.com/qq/qq02-data-sharing-with-class.html. Круто придумано, нечего сказать ![]() |
Автор: SABROG 25.7.2008, 11:10 |
Так, значит речь идет http://doc.trolltech.com/4.4/qshareddata.html, http://doc.trolltech.com/4.4/qshareddatapointer.html и http://doc.trolltech.com/4.4/qsharedmemory.html, и http://doc.trolltech.com/4.4/qexplicitlyshareddatapointer.html Народ, поздравлю всех с Днем Системного Администратора |
Автор: Любитель 25.7.2008, 14:06 |
Ну да, писал по памяти - ошибся ![]() |
Автор: aspirin2003 26.7.2008, 18:25 | ||
Но только в случае, когда методы не модифицируют данные, так? |
Автор: anatox91 26.7.2008, 19:02 |
aspirin2003, ну если модифицируют, то можно сделать эти данные mutable, но все конечно зависит от ситуации |
Автор: aspirin2003 27.7.2008, 10:47 | ||||||
Попробовал переписал класс с использованием QSharedData. Вот примерно то, что получилось: calcelement.h
calcelement.cpp
MSVC этот код компилит нормально, все работает. А gcc ругается в этой строке:
no match for 'operator=' in 'res = CalcElement::operator+(CalcElement&)(((CalcElement&)(+m1)))' calcelement.cpp Помогите пожалуйста разобраться, в чем косяк. |
Автор: aspirin2003 27.7.2008, 19:39 |
Ни у кого никаких соображений? Просто надо чтобы программа работала и под Linux тоже, а gcc ругается :( |
Автор: nickless 28.7.2008, 21:14 | ||||
aspirin2003, типы операторам надо давать не какие попало, а какие положено ![]() *.h
*.cpp
|
Автор: aspirin2003 29.7.2008, 15:17 |
nickless Спасибо! Все заработало! |
Автор: WizardNG 26.7.2019, 14:59 |
удалено |