Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Qt
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/14: Рейтинг темы: голосов - 14, средняя оценка - 4.64
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
1

Копирование функции

15.07.2019, 13:39. Просмотров 2606. Ответов 19
Метки нет (Все метки)

Доброго времени суток!
Предположим у меня есть некая функция (Назовем ее Foo), которая возвращает строку (QString) и принимает n-ое количество параметров:
C++ (Qt)
1
2
3
4
5
6
QString Foo(int var)
{
      QString str;
      str = "....";
      return str;
}
Теперь у меня появилась необходимость в том, чтобы эта же функция отработала для другого объекта, но вернула к примеру другую строку (QString SecondString). Лично я выход из этой ситуации вижу только следующий:
Создать точно такую же функцию, но с другим названием и в при необходимости вызывать ее.
Казалось бы ладно, создам еще одну, но таких "копий" функций понадобится много. Т.е. допустим у меня есть 100 функций которые возвращают str. И к каждой такой функции нужна одна копия, в сумме 200.
Можно ли как-то более разумно этот вопрос решить?
P.S. пока писал, идея в голову пришла. В параметры передавать то, какой объект вызывает эту функцию. Как думаете?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2019, 13:39
Ответы с готовыми решениями:

Копирование значений из функции в объект
Подскажите пожалуйста как скопировать значения из функции void fc(a& z1, a& z2, a& z3) так...

Копирование файлов с использованием unicode-функции
Оригинал кода тут:сообщение Я решил преобразовать кусок кода для работы с Unicode - функциями....

Что происходит раньше - копирование возвращаемого значения из функции или освобождение ресурсов?
Здравствуйте! Реализую синглтон типа "феникс". Т. е. когда он никому не нужен, он самоудаляется,...

Необходимые функции:1)перенос/копирование файлов; 2)нахождение новых папок; 3) автозапуск; 4) работа с электронной почтой
Помогите по возможности плиз, очень надо для практики! На повестке дня следующие мини-задачи: ...

Копирование определенного текста из файла, копирование и вставка в статичную переменную
Доброго вечера. Делаю программу которая бы выводила погоду на сегодня через данные сайта. Завис на...

19
Анна по жизни
270 / 161 / 60
Регистрация: 13.03.2019
Сообщений: 396
15.07.2019, 14:38 2
Лучший ответ Сообщение было отмечено MetMark как решение

Решение

Цитата Сообщение от MetMark Посмотреть сообщение
P.S. пока писал, идея в голову пришла. В параметры передавать то, какой объект вызывает эту функцию. Как думаете?
Если есть возможность, то сделать эту функцию методом объекта Включить метод в базовый класс и перегружать в наследующем классе.

Ну... или так, как пришла идея.
1
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
15.07.2019, 14:44  [ТС] 3
Анна по жизни, К сожалению нет возможности. Эти функции никак не привязаны ни к чему и вызываются в зависимости от ситуаций. Вы уже предлагали данный вариант и я использую его для отрисовки дополнительных линий у геометрических фигур. Еще раз спасибо большое!
0
peter_irich
65 / 60 / 19
Регистрация: 18.10.2017
Сообщений: 578
15.07.2019, 21:24 4
Если есть возможность из функции определять, для какого объекта она вызвана, то по этому.
Например, если слот кто-то вызвал, то можно установить для вызывающих удобное имя и
в слоте его получать. Я так делаю для однородных объектов, например, для кнопок.
0
15.07.2019, 21:24
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
16.07.2019, 08:55  [ТС] 5
peter_irich, Пока еще не начал писать реализацию своей идеи, но ваша идея меня чем-то заманила, правда не знаю как ее реализовать в своем случае.
У меня есть 2 объекта, к примеру QLabel и они оба вызывают эту функцию, но получать на выходе из функции должны разные значения. Как функции дать понять что я вызвал FirstLabel, а не SecondLabel или наоборот!?
0
TRam_
зомбяк
1246 / 936 / 278
Регистрация: 14.05.2017
Сообщений: 3,044
16.07.2019, 13:22 6
Если речь о просто функции - никак. Если речь о слоте у QObject, то там есть метод sender(), который и позволяет определять кто данный слот вызвал - https://doc.qt.io/qt-5/qobject.html#sender
1
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
16.07.2019, 14:09  [ТС] 7
TRam_, К сожалению нет, просто функции. Конечно можно создать какой-нибудь класс и унаследовать от Q_OBJECT, но это будет уж слишком... Спасибо всем большое!
0
peter_irich
65 / 60 / 19
Регистрация: 18.10.2017
Сообщений: 578
16.07.2019, 21:42 8
TRam_, не так просто. sender() - protected(). Надо создать свой, например,
C++ (Qt)
1
2
3
QObject * mainwdg::my_sender(){
  return sender();
}
и уже его вызывать в своём обработчике имени объекта.

Добавлено через 2 минуты
MetMark, надо присвоить объектам типа QLabel разные имена одного типа и их анализировать.
Получать - да, через sender().
1
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
16.07.2019, 21:56  [ТС] 9
peter_irich, Мало чего понял. Это вы к чему? На это отвечаете?:
Цитата Сообщение от MetMark Посмотреть сообщение
Конечно можно создать какой-нибудь класс и унаследовать от Q_OBJECT
Цитата Сообщение от peter_irich Посмотреть сообщение
sender() - protected()
Это что значит? Функция sender() относится к защищенным?

Цитата Сообщение от peter_irich Посмотреть сообщение
C++ (Qt)
1
2
3
QObject * mainwdg::my_sender(){
* return sender();
}
Создаю указатель на нужный мне виджет, а потом в этой функции возвращаю указатель???
И где это записывать?

И последний вопрос: это разве удобнее чем просто посылать параметром в функцию к примеру имя или номер виджета при вызове функции.
И еще. Виджетами я пользуюсь через указатели, которые объявляю в private в классе. (Да, у меня класс, который содержит в себе виджеты)
А функции еще раз, ни к чему не привязаны, они просто написаны в .h файле (хедере)
0
peter_irich
65 / 60 / 19
Регистрация: 18.10.2017
Сообщений: 578
16.07.2019, 22:53 10
MetMark, да, функция sender() относится к protected.
Возвращаете указатель на вызвавший объект.
Вот как я её использую:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
QObject *mainwdg::get_ob_ind(int *ind, int *len, char *buf) {
//returns sender, sender index in ind,QObject name in buf.
        QObject *po;
        QString qsn;
        int i1, i2;
        bool b;
        po = my_sender();
        qsn = po->objectName();
        strcpy(buf, qsn.toLatin1().data());
        i1 = qsn.section(QChar('_'), -1, -1).toInt(&b);
        if (!b)
                i1 = -1;
        *ind = i1;
        i2 = qsn.section(QChar('_'), -2, -2).toInt(&b);
        if (!b)
                i2 = -1;
//fprintf(stdout,"set_ob_ind: %d %d %s\n",i1,i2,qsn.toLatin1().data());fflush(stdout);
        *len = i2;
        return po;
}
А имя объекта устанавливается функцией setObjectName() произвольно, как вам удобнее.
И всё эт вы могли найти и сами.
1
Анна по жизни
270 / 161 / 60
Регистрация: 13.03.2019
Сообщений: 396
17.07.2019, 12:08 11
Цитата Сообщение от peter_irich Посмотреть сообщение
не так просто. sender() - protected(). Надо создать свой, например,
Не надо ничего создавать. методы из секции protected доступны потомками от QObject.
1
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
17.07.2019, 12:52  [ТС] 12
Анна по жизни, Погодите, я могу в функциях, где есть необходимость возвращать указатель на тот объект, который вызвал функцию, а потом использовать его для определения того, что мои функции должны вернуть?
0
Анна по жизни
270 / 161 / 60
Регистрация: 13.03.2019
Сообщений: 396
17.07.2019, 14:42 13
Лучший ответ Сообщение было отмечено MetMark как решение

Решение

Цитата Сообщение от MetMark Посмотреть сообщение
где есть необходимость возвращать указатель на тот объект, который вызвал функцию, а потом использовать его для определения того, что мои функции должны вернуть?
Давай вернёмся к твоему первому посту.
Я так поняла, что у тебя есть некоторая функция, не принадлежащая ни одному из классов, которая должна что-то проделывать с объектами разного типа.
Тогда тебе нужен такой вариант: передавать в эту функцию объект, с которым ты будешь что-то проделывать, как один из параметров. Если предполагается, что классы этих объектов наследуют от какого-то базового класса, то типом аргумента будет указатель на базовый класс. НАпример, у тебя есть объекты двух типов MyClass_1 и MyClass_2, которые наследуют от BaseClass, то

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
QString Foo(int var, BaseClass *obj) // сюда передаём указатель на любой твой объект, если его класс наследует от BaseClass
{ 
   QString str;
   // если тебе надо разделять объекты по типам, то организуем проверку, что же конкретно за тип у объекта obj
   MyClass_1 *o1 = dynamic_cast<MyClass_1>(obj); 
   // если obj имеет тип  MyClass_1, указатель o1 проинициализируется тем же значением, что и obj. Если нет - o1 равен 0;
   if(o1)
   {
      // здесь делаешь то, что надо проделать с объектами типа   MyClass_1.
      str = "....";
      return str;
   } 
 
   // аналогично для другого типа
   MyClass_2 *o2 = dynamic_cast<MyClass_2>(obj); 
   if(o2)
   {
      ...
   }
   
   return QString(); // не нашлось кода для обработки объеста
}
где-то в твоём коде будет вызов:

C++ (Qt)
1
2
3
4
MyClass_2 *myObj = new MyClass_2();
...
 
QString s = Foo(5, myObj);
каждый раз, когда у тебя будет появляться новый класс, объекты которого надо обрабатывать в этой функции, тебе придётся дописывать сюда новую секцию. Если у тебя будет 100 функций, которые хотят обрабатывать объекты разных типов по-разному, в каждую из них будешь добавлять такие секци. Это не очень хорошее решение. Гораздо лучшим было бы определить QString Foo(int) - методом твоего базового класса, от которого наследуют все обрабатываемые объекты; в классах-потомках (MyClass_1 и MyClass_2) реализовать обработку для соответсвующего типа (маленькое тельце без вот всех этих страшных dynamic_cast), а вызов тогда будет выглядеть так:

C++ (Qt)
1
2
3
4
5
MyClass_1 *myObj = new MyClass_1();
 
...
 
QString s =myObj.Foo(5);
Если у тебя будет 100 различных классов, каждый из которых требует индивидуальной обработки в Foo(), ты всё равно не избежишь написания 100 различных реализаций, но такой подход лучше, чем шарить по одной огромной функции в поисках куска, обрабатывающего конкретный тип.
1
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
17.07.2019, 15:06  [ТС] 14
Цитата Сообщение от Анна по жизни Посмотреть сообщение
Гораздо лучшим было бы определить QString Foo(int) - методом твоего базового класса, от которого наследуют все обрабатываемые объекты; в классах-потомках (MyClass_1 и MyClass_2) реализовать обработку для соответсвующего типа
Все объекты, которые предполагают передаваться в функцию находятся и создаются в одном классе, который в свою очередь наследует от QWidget.
Цитата Сообщение от Анна по жизни Посмотреть сообщение
каждый раз, когда у тебя будет появляться новый класс, объекты которого надо обрабатывать в этой функции, тебе придётся дописывать сюда новую секцию.
В моем коде нет классов потомков. В моем BaseClass в private: происходит создание указателей на некоторые виджеты (QLabel к примеру). В зависимости от конкретного QLabel функция Foo должна возвращать конкретные для этого объекта данные типа QString.
При создании и отображении моего объекта класса BaseClass получается так, что выводится определенное количество правильно расставленных виджетов, в которых уже есть информация, благодаря функциям, на подобии Foo (Вот таких как раз таки и 100(примерно)). Это я сделал для того, чтобы в каждом цикле, где нужно вывести эту "ораву" виджетов, не вызывать и не заполнять постоянно ручками все, а всю работу свалил на класс, объект которого все за меня будет делать. Т.е. один раз написал класс, а уже в зависимости от параметров создаваемого объекта выводится то, что нужно
Ваш вариант очень удобен, т.к. на выходе мы будем иметь очень маленькие методы/функции, что является хорошей манерой, но реализовать в моем случае я не думаю что получится.
Спасибо за объяснение, понял как это можно сделать, спасибо огромное!!!!
0
Анна по жизни
270 / 161 / 60
Регистрация: 13.03.2019
Сообщений: 396
17.07.2019, 15:30 15
Тогда возможен вариант с objectName() как описывалось выше:

C++ (Qt)
1
2
3
4
5
QString Foo(int , QWidget* obj)
{
   QStrung wName = obj->objectName();
// а дальше уже парсер для wName и реализации для конкретных имён;
}
1
peter_irich
65 / 60 / 19
Регистрация: 18.10.2017
Сообщений: 578
17.07.2019, 21:29 16
Анна по жизни, вроде бы, когда я когда-то давно столкнулся с необходимостью вызвать sender(),
то непосредственно он не вызывался, поэтому потребовалось создать свой. Но я уже абсолютно не помню,
что это был за объект.
0
Анна по жизни
270 / 161 / 60
Регистрация: 13.03.2019
Сообщений: 396
18.07.2019, 00:59 17
Цитата Сообщение от peter_irich Посмотреть сообщение
вроде бы, когда я когда-то давно столкнулся с необходимостью вызвать sender(),
то непосредственно он не вызывался
Видимо, надо было отдать указатель на отправителя сигнала куда-то наружу.
0
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
18.07.2019, 21:57  [ТС] 18
Анна по жизни,
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void MainWindow::ShowNameFigure(QWidget *obj)
{
    QString objectName = obj->objectName();
    if (objectName == "Parallelepiped")
    {
        Cube->label();
        Parallelepiped->label();
    }
    if (objectName == "Pyramid")
    {
        Tetrahedron->label();
    }
    if (objectName == "ptrButtonBackToTheChoiceFigure")
    {
        Parallelepiped->label();
        Ball->label();
        Cone->label();
        Cylinder->label();
//        Pyramid->label(); пока нет, потом допишу эту фигуру
        Prism->label();
    }
}


Эту функцию я запихнул в слоты, чтобы ее было отовсюду видно. Так вот obj->objectName(); возвращает "" (Проверил через qDebug).Не понимаю почему так...

Вызвал функцию в конструкторе так:
C++ (Qt)
1
ShowNameFigure(ptrButtonBackToTheChoiceFigure);
0
Анна по жизни
270 / 161 / 60
Регистрация: 13.03.2019
Сообщений: 396
19.07.2019, 00:23 19
Лучший ответ Сообщение было отмечено MetMark как решение

Решение

А такая строчка есть после создания кнопки?
C++ (Qt)
1
ptrButtonBackToTheChoiceFigure->setObjectName("ptrButtonBackToTheChoiceFigure");
1
MetMark
0 / 0 / 0
Регистрация: 04.05.2018
Сообщений: 199
19.07.2019, 00:41  [ТС] 20
Анна по жизни, Понял, благодарю
0
19.07.2019, 00:41
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.07.2019, 00:41

Excel. Копирование столбца, при заполнении 22-й строки продолжить копирование в соседний столбец
Всем привет. Задача: Есть таблица Excel, заполнены 2 столбца, из них первый - порядковые номера,...

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

Копирование: Ввод имени папки и копирование из нее файлов
Доброго времени суток! Реально ли реализовать подобное с помощью bat ? Знаю, что можно создать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru