Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ передача QString функции собственному классу

Автор: danya 10.11.2010, 13:50

попробовал сделать следующим образом:
в основной форме:

QString str = QFileDialog::getOpenFileName(this, "Select File", "", "*.ini");
    base::base file;
    flat=file.open_base(str);

в классе есть функция:
int base::open_base(QString file)
{
    QSettings baza(file,QSettings::IniFormat);
    baza.beginGroup("Config");
    flat=baza.value("FLATS","").toInt();
    return flat;
}

в результате получаю ошибку:
error: no match for call to '(QSettings) (QString&, QSettings::Format)'

подскажите что я делаю не так или хотябы что в какую сторону копять?

Автор: panter_dsd 10.11.2010, 13:57

Все, вроде, правильно. Версия Кьюта какая?

Автор: danya 10.11.2010, 14:20

Цитата(panter_dsd @ 10.11.2010, 14:57) *
Все, вроде, правильно. Версия Кьюта какая?

4.7.0

Автор: panter_dsd 10.11.2010, 14:48

Интересно. Код сюда приложить сможешь?

Автор: kwisp 10.11.2010, 14:53

Цитата(danya @ 10.11.2010, 13:50) *
error: no match for call to '(QSettings) (QString&, QSettings::Format)'

по-моему такая ошибка если из текущей области видимости(в данном случае файла) не видно обЪявления функции(в данном случае конструктора QSettings) проще говоря предполагаю что не хватает # include <QtCore/QSettings> в файле в котором ошибка.

Автор: panter_dsd 10.11.2010, 14:56

Тогда писало бы что

Цитата
error: 'QSettings' was not declared in this scope

Автор: danya 10.11.2010, 15:11

Цитата(panter_dsd @ 10.11.2010, 15:48) *
Интересно. Код сюда приложить сможешь?

да конечно
только не пугайтесь на кол-во закомментированного кода
я ведь только учусь:) http://narod.ru/disk/27267093000/kvartplata.7z.html

Автор: panter_dsd 10.11.2010, 15:17

Там совсем в другом ошибка:
1. base::base file; замени на base file;
2. В base.cpp
baza(file,QSettings::IniFormat); замени на QSettings baza(file,QSettings::IniFormat);

Автор: kwisp 10.11.2010, 15:27

Цитата(panter_dsd @ 10.11.2010, 15:17) *
2. В base.cpp
baza(file,QSettings::IniFormat); замени на QSettings baza(file,QSettings::IniFormat);

в приведенном в посте коде так и есть. или я туплю?

Автор: panter_dsd 10.11.2010, 15:28

Ты прав. Но в исходниках другое. ТС походу запутался немного. :)

Автор: danya 10.11.2010, 15:28

Цитата(panter_dsd @ 10.11.2010, 16:17) *
Там совсем в другом ошибка:
1. base::base file; замени на base file;
2. В base.cpp
baza(file,QSettings::IniFormat); замени на QSettings baza(file,QSettings::IniFormat);

2 так раньше и было)
а вот первое действительно тупанул спасибо!

Автор: kwisp 10.11.2010, 15:58

danya,
у тебя же есть член класса baza зачем локальную переменную в функции open_base тоже называешь baza при том она того же типа что и член класса!
Это тебя путает. Так делать не рекомендуется. назови по другому.

А если ты хочешь инициализировать член класса с именем baza то тебе надо написать не
baza(file,QSettings::IniFormat);
и не
QSettings baza(file,QSettings::IniFormat);
а
baza = QSettings(file,QSettings::IniFormat);
к моменту вызова open_base baza уже существует созданная конструктором по умолчанию.

Автор: danya 10.11.2010, 19:39

Цитата(kwisp @ 10.11.2010, 16:58) *
danya,
у тебя же есть член класса baza зачем локальную переменную в функции open_base тоже называешь baza при том она того же типа что и член класса!
Это тебя путает. Так делать не рекомендуется. назови по другому.

А если ты хочешь инициализировать член класса с именем baza то тебе надо написать не
baza(file,QSettings::IniFormat);
и не
QSettings baza(file,QSettings::IniFormat);
а
baza = QSettings(file,QSettings::IniFormat);
к моменту вызова open_base baza уже существует созданная конструктором по умолчанию.

сделал)
появилась следующая ошибка
 error: 'QSettings& QSettings::operator=(const QSettings&)' is private

в
baza = QSettings(file,QSettings::IniFormat);


Автор: Litkevich Yuriy 10.11.2010, 20:13

Всё верно, QSettings не имеет отрытого оператора присваивания и конструктора копирования.
Этот класс предназначен для создания локальной переменной, так всюду в примерах и применяется.

Автор: kwisp 11.11.2010, 11:32

danya,
я просто исходники твои скачал.
про то что оператор копирования закрыт это я проглядел в документации.
получается тебе не нужны члены класса QSettings baza и еще какой то не помню уже т.к. исходники удалил:)

Автор: danya 11.11.2010, 13:45

Цитата(kwisp @ 11.11.2010, 12:32) *
danya,
я просто исходники твои скачал.
про то что оператор копирования закрыт это я проглядел в документации.
получается тебе не нужны члены класса QSettings baza и еще какой то не помню уже т.к. исходники удалил:)

да я уже по другому сделал сделал общим переменную file вообщем сейчас всё работает спасибо всем :)

Автор: Obey-Kun 1.12.2010, 6:56

Не следует передавать QString через копию. Лучше — через константную ссылку: int base::open_base(const QString &file). Такой метод будет вызываться быстрее.

Автор: Алексей1153 1.12.2010, 7:45

Obey-Kun, иногда бывает так, что нет объекта, ссылку на который можно передать :) Тогда лучше иметь перегрузку с параметром по значению

Автор: Obey-Kun 1.12.2010, 10:54

Цитата(Алексей1153 @ 1.12.2010, 7:45) *
Obey-Kun, иногда бывает так, что нет объекта, ссылку на который можно передать :) Тогда лучше иметь перегрузку с параметром по значению

Так перегрузку или параметр по умолчанию? :)

Перегрузка:
myMethod(const QString &string);
myMethod();


Параметр по умолчанию:
myMethod(QString string = "");


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

Автор: Litkevich Yuriy 1.12.2010, 11:22

Цитата(Obey-Kun @ 1.12.2010, 8:56) *
Такой метод будет вызываться быстрее.
в общем случае да, а в с лучае с QString - нет. Т.к. QString копирует данные, только при изменении оригинала/копии.
Этот класс специально оптимизирован

Автор: Алексей1153 1.12.2010, 12:02

Цитата(Obey-Kun @ 1.12.2010, 12:54) *
Так перегрузку или параметр по умолчанию

про перегрузку

myMethod(const QString &string); //тут можно передать ссылку на QString
myMethod(const QString string); // а тут можно просто строку символов. Объект QString создастся и будет равносильно передаче по значению

но зато гибко :)





Цитата(Litkevich Yuriy @ 1.12.2010, 13:22) *
QString копирует данные,

мфсишный CString себя так же ведёт :) Я однажды это для себя открыл вдруг - передал в функцию CString по значению, потом в функции редактировал внутренний буфер вручную. Хоп! Смотрю, внешний объект тоже поменялся )) Костыль - сначала явно скопировать в другой объект.

Автор: Obey-Kun 1.12.2010, 12:05

Да, забыл об implicit sharing.

Но в любом случае, для передачи объектов, sizeof которых больше sizeof указателя (а это ограничивается почти всеми стандартными типами и элементами enum'ов), в качестве аргументов, во всех методах в Qt применяются именно константные ссылки, куда ни глянь.

Возможно, потому, что тут всё равно приходится совершать какие-никакие действия по копированию объекта.

Автор: BRE 1.12.2010, 12:06

Что-то я не пойму о чем речь?
И первый и второй метод спокойно можно вызывать так:

myMethod( "text" );


В обоих случаях будет создан временный объект QString.

Автор: Obey-Kun 1.12.2010, 12:08

Если ты о моём примере, то нет, при передаче по ссылке никакой копии создаваться не будет.
При передаче по копии, будет создана копия, но содержимое QString (буковки) не будут копироваться (из-за Impicit Sharing).

Автор: Алексей1153 1.12.2010, 12:09

BRE, да, но когда передаёшь QString, не происходить аллокации для строки, а когда передаётся строку символов, происходит создание объекта и аллокация памяти под копию буфера символов. Вот об этом речь

Автор: Obey-Kun 1.12.2010, 12:11

По моему, чем делать заведомо менее эффективный метод для иллюзии удобства, лучше делать так:

myFunc(const QString &string) {
    qDebug() << string;
}

QString s("tatata");
myFunc(s);
myFun(QString("nanana"));

Автор: Алексей1153 1.12.2010, 12:15

Obey-Kun, визуальное загромождение кода тоже мало способствует удобству :) Мы же знаем, что QString так работает (да и сами разработчики так его применяют - это о чём-то говорит).
А в общем случае, конечно, по ссылке или по указателю большие объекты передавать следует. За исключением случаев, когда внутренний объект будет меняться - тогда проще сразу на стеке его и создать

Автор: BRE 1.12.2010, 12:15

Если методу нужен в качестве параметра QString, то по любому нужно создавать объект.
А передача константной ссылки всегда "легче" чем передача по значению, хотя с классами используемыми implicit sharing это и не так явно.

Автор: Obey-Kun 1.12.2010, 12:20

Цитата(Алексей1153 @ 1.12.2010, 12:15) *
Obey-Kun, визуальное загромождение кода тоже мало способствует удобству :) Мы же знаем, что QString так работает (да и сами разработчики так его применяют - это о чём-то говорит).
А в общем случае, конечно, по ссылке или по указателю большие объекты передавать следует. За исключением случаев, когда внутренний объект будет меняться - тогда проще сразу на стеке его и создать


Поищите, например, setName в документации. Да у них там везде QString передаётся по константной ссылке. Абсолютно везде.
При создании копии QString, несмотря на общее использование данных, кое-какие лишние действия всё равно будут проводиться.

Цитата
А передача константной ссылки всегда "легче" чем передача по значению, хотя с классами используемыми implicit sharing это и не так явно.

Вот именно. Но разница всё равно есть. И разработчики Qt, видимо, посчитали её значительной, иначе в собственных методах использовали бы передачу QString по значению.

Автор: Алексей1153 1.12.2010, 12:31

Obey-Kun, непонятно, о чём такой долгий спор :) Всем и так известно, что ссылка (или указатель) передаётся быстрее и меньше стека есть. Думаешь, Антарктиду открыл ? ;)
Только в каждом случае , когда пишешь свою функцию, нужно продумывать интерфейс, так как тупо всегда ссылку или указатель нельзя передавать. Бывает так, что надо именно объект, чтобы он сразу скопировался

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)