Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
4 / 4 / 1
Регистрация: 17.12.2015
Сообщений: 119
1

Оптимален ли метод, проверяющий кликабельность кнопки

23.07.2016, 21:30. Показов 2513. Ответов 61
Метки нет (Все метки)

Я тут решил написать класс "Кнопка", в котором есть метод проверяющий кликабельность(не знаю как назвать правильно) и получилась очень большое условие.
Вопрос в том, нормальны ли такие проверки или это очень плохо

C++
1
2
3
4
5
6
7
8
9
10
11
bool Button::isClicked(RenderWindow& window)
{
    if(Mouse::isButtonPressed(Mouse::Left) &&
       Mouse::getPosition(window).x > sprite.getPosition().x &&
       Mouse::getPosition(window).y > sprite.getPosition().y &&
       Mouse::getPosition(window).x < sprite.getPosition().x + texture.getSize().x * sprite.getScale().x &&
       Mouse::getPosition(window).y < sprite.getPosition().y + texture.getSize().y * sprite.getScale().y)
        return true;
    else
        return false;
}
P.S. пользуюсь SFML
1

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.07.2016, 21:30
Ответы с готовыми решениями:

Метод, проверяющий истинность выражения
Задача должна быть построена на методах класа.Проверить истинность выражения. Cреди трех данных...

Метод проверяющий является ли экземпляр наследником
Надо что бы наследники менял цвет в консоли class Printer { protected ConsoleColor...

Создать в классе Circle метод, проверяющий, касаются ли окружности в одной точке
Создайте в классе Circle метод, проверяющий, касаются ли окружности в одной точке. Учтите, что...

Сгенерировать список номеров. Сделать метод, проверяющий наличие номера в списке
Помогите пожалуйста сгенерировать список номеров и сделать метод, который будет проверять наличие...

61
98 / 71 / 13
Регистрация: 15.12.2013
Сообщений: 453
23.07.2016, 21:36 2
А чем она Вам не нравится? Если считаете, что она запутанная, добавьте комментарий.
1
4 / 4 / 1
Регистрация: 17.12.2015
Сообщений: 119
23.07.2016, 21:58  [ТС] 3
просто интересно, это нормально, когда в одном if так много действий/условий
0
Заблокирован
23.07.2016, 22:07 4
Цитата Сообщение от JackLas Посмотреть сообщение
просто интересно, это нормально, когда в одном if так много действий/условий
- нет конечно, вот оптимизированная версия твоего кода
C++
1
2
3
4
5
6
7
8
9
10
bool Button::isClicked(RenderWindow& window)
{
    if(Mouse::isButtonPressed(Mouse::Left) )
    if(Mouse::getPosition(window).x > sprite.getPosition().x )
    if(Mouse::getPosition(window).y > sprite.getPosition().y )
    if(Mouse::getPosition(window).x < sprite.getPosition().x + texture.getSize().x * sprite.getScale().x)
    if(Mouse::getPosition(window).y < sprite.getPosition().y + texture.getSize().y * sprite.getScale().y)
        return true;
    return false;
}
Добавлено через 3 минуты
JackLas, чтобы было понятно почему я забраковал твой код возьмём задачу , в сундуке лежат кубики и шары разных цветов, тебе надо найти зелёный шар в красную крапинку
итак
первый этап - проверяем кубик мы вытащили или шарик
второй этап - проверяем является ли шарик зелёным
третий этап - является ли шар в крапинку
четвёртый этап - является ли крапинка красной
если все четыри этапа пройдены - возврат истины

Конечно же можно загантать всё под одно условие, но тогда для куба(который отбракуется ещё на первом этапе) мы будем выполнять уже никому ненужные проверки, на цвет и крапинку. В итоге если работаем с большой выборкой данных получим колосальное замедление, т.к сделаем больше работы.
0
586 / 395 / 147
Регистрация: 01.10.2015
Сообщений: 1,162
23.07.2016, 22:07 5
Цитата Сообщение от Unknownx Посмотреть сообщение
вот оптимизированная версия
и в чем заключается "оптимизация"?
0
Заблокирован
23.07.2016, 22:11 6
Цитата Сообщение от 0x90h Посмотреть сообщение
и в чем заключается "оптимизация"?
читай выше(меньше работы делается), это крайне очевидно.

Добавлено через 2 минуты
if(Mouse::isButtonPressed(Mouse::Left) )[/quote] - подумай что будет если была нажата правая кнопка в этом варианте и в твоём изначальном
Цитата Сообщение от JackLas Посмотреть сообщение
if(Mouse::isButtonPressed(Mouse::Left) &&
* * * *Mouse::getPosition(window).x > sprite.getPosition().x &&
* * * *Mouse::getPosition(window).y > sprite.getPosition().y &&
* * * *Mouse::getPosition(window).x < sprite.getPosition().x + texture.getSize().x * sprite.getScale().x &&
* * * *Mouse::getPosition(window).y < sprite.getPosition().y + texture.getSize().y * sprite.getScale().y)
, где сделатся больше работы просто чтобы отбраковать правый клик?
0
Эксперт С++
8342 / 4025 / 883
Регистрация: 15.11.2014
Сообщений: 9,056
23.07.2016, 22:13 7
Цитата Сообщение от 0x90h Посмотреть сообщение
и в чем заключается "оптимизация"?
ни в чем.

Цитата Сообщение от Unknownx Посмотреть сообщение
Конечно же можно загантать всё под одно условие, но тогда для куба(который отбракуется ещё на первом этапе) мы будем выполнять уже никому ненужные проверки,
вам нужно подучить с++.
логические вычисления - ленивые.

C++
1
if (A && B)
если результат выражение А - ложь,
тогда B уже не будет вычисляться,
итак понятно, что результат всего выражения - ложь
0
586 / 395 / 147
Регистрация: 01.10.2015
Сообщений: 1,162
23.07.2016, 22:14 8
hoggy, опередил... Я не зря заключил слово оптимизация в кавычки...
0
Эксперт С++
8342 / 4025 / 883
Регистрация: 15.11.2014
Сообщений: 9,056
23.07.2016, 22:18 9
Цитата Сообщение от Unknownx Посмотреть сообщение
это крайне очевидно.
мне крайне очевидно, что в выражении:
C++
1
if(!text.empty() && text[0]=='A')
если текст - пуст, то уже нет никакой причины
пытаться брать его первую несуществующую буковку,
и нарываться на выход за приделы диапазона.
0
👻👻👻
20 / 27 / 12
Регистрация: 22.04.2016
Сообщений: 166
23.07.2016, 22:32 10
Unknownx, Если копилятор встречает &&, перед которым ложное выражение, то следующее выражение он не будет проверять, так что это не оптимизация

Добавлено через 6 минут
Кстати, ТС, ничего страшного нет в ваших пяти строчках.
0
1354 / 992 / 314
Регистрация: 28.07.2012
Сообщений: 2,750
23.07.2016, 22:42 11
Цитата Сообщение от JackLas Посмотреть сообщение
Я тут решил написать класс "Кнопка", в котором есть метод проверяющий кликабельность
Я вот вообще не уверен, что кнопка, которая имеет доступ как к мышке, так и ко всем окнам - это правильное решение.
Кнопка - это слишком мелкая сущность, она должна быть практически бесправной.
Желателен некоторый глобальный супервизор, который контролирует мышку и сообщает кнопке ее нажатиях.
0
Заблокирован
23.07.2016, 22:46 12
Цитата Сообщение от daniilorain Посмотреть сообщение
Unknownx, Если копилятор встречает &&, перед которым ложное выражение, то следующее выражение он не будет проверять, так что это не оптимизация
Мы о рантайме говорим, а не о статической линковке?Какой компилятор при работе ехе?

Добавлено через 2 минуты

Не по теме:

Чтобы проверить выражение

Цитата Сообщение от Unknownx Посмотреть сообщение
перед которым ложное выражение,
нужно выполнить действие, ладно иди читай книги, а то нервы только себе добавляю

0
👻👻👻
20 / 27 / 12
Регистрация: 22.04.2016
Сообщений: 166
23.07.2016, 23:05 13
Unknownx, Да, ошибся, не о том подумал

Добавлено через 11 минут
Выражение слева как раз и проверено, иначе как оно стало ложным...
0
4478 / 2095 / 265
Регистрация: 01.03.2013
Сообщений: 5,556
Записей в блоге: 22
23.07.2016, 23:16 14
Unknownx, вы эпичнейшим образом сели в лужу и продолжаете в ней валяться несмотря на все попытки вас вразумить....

Цитата Сообщение от daniilorain Посмотреть сообщение
Кстати, ТС, ничего страшного нет в ваших пяти строчках.
А мне совершеннейшим образом очевидно, что кот
C++
1
if (a && b) return true; else return false;
обычно пишется как
C++
1
return a && b;
4
👻👻👻
20 / 27 / 12
Регистрация: 22.04.2016
Сообщений: 166
23.07.2016, 23:23 15
_Ivana, ваш вариант хороший, но я говорил о проверке в несколько строчек в общем, не всегда же нужно возвращать значение a && b, а что-то проверить и выполнить в if(ну, или else). Кстати, это было ИМХО.

Добавлено через 52 секунды
И ещё "кстати": коты обычно мяукают, а не "пишутся"
0
2540 / 1199 / 358
Регистрация: 30.11.2013
Сообщений: 3,820
23.07.2016, 23:43 16
Лучший ответ Сообщение было отмечено JackLas как решение

Решение

При всем уважении колеги, но раз вы не помогаете ТСу, а лишь приклеиваете лейкопластырь к ране, вместо лечения - то попробую я помочь ТСу

1) почему метод не константный?
2) почему ссылка приходит не константная - вы в методе isClicked собираетесь менять объект window ?
3) Для вашего случая нужен уровень абстракции: window == прямоугольник( Rect ), клик == точка (Point) - итого всё сводится к написанию для всех случаев находится ли точка в прямоугольники в классе Rect.
4) Насчёт множественного if'a - я бы советывал такое форматирование и код:

C++
1
2
3
4
5
6
7
bool Rect::Contains( const Point& p ) const 
{
    return x <= point.x 
        && point.x < x + width 
        && y <= point.y 
        && point.y < y + height;
}
12
586 / 395 / 147
Регистрация: 01.10.2015
Сообщений: 1,162
24.07.2016, 00:57 17
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
При всем уважении колеги, но раз вы не помогаете ТСу
Ваш упрек не совсем справедлив. В изначальной версии кода, ТС передает ссылку на RenderWindow& window - собственно, в контексте SFML, это окошко ОС, на котором осуществляется рисование всей игры - в качестве параметра метода самой (sic!) кнопки. Причем делает это для того, чтобы проверить событие щелчка мышом на этой же кнопке.

Выше, nonedark2008 уже говорил о том, что обработка этого события должна осуществляться менеджером событий, причем в контексте определенного состояния игры, а делегирование таких полномочий кнопке - не лучшее решение (ИМХО).

Резюмируя, рискну предположить, что ТС только-только начал осваивать SFML, да и его вопрос был больше связан с самим ЯП, по поводу чего он и получил консультацию. А то, что народ подзабыл указать на константность метода/параметра - следствие общего увлечения "опущением" в азы вычисления Булевых выражений в С++ некоторых любителей "оптимизации".
0
98 / 71 / 13
Регистрация: 15.12.2013
Сообщений: 453
24.07.2016, 01:34 18
Цитата Сообщение от Unknownx Посмотреть сообщение
- мальчик ты в своём уме? Мы о рантайме говорим, а не о статической линковке?Какой компилятор при работе ехе?Иди букварь прочти.
То есть по твоему if работает как constexpr if? Мб ты ассемблерный листинг этого кода приведешь, прежде чем оскорблять? Или хотя-бы сам разберешься?

Добавлено через 14 минут
Unknownx,

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <cstdio>
 
bool func(bool a1, bool a2, bool a3, bool a4, bool a5)
{
    return a1 && a2 && a3 && a4 && a5;
}
 
int main(int argc, char** argv)
{
    (void)argc;
    (void)argv;
 
    volatile bool var = false;
    std::printf("%d", func(true, true, true, true, var));
 
    return 0;
}
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
_Z4funcbbbbb:
.LFB0:
    .file 1 "/home/mint/Develop/cbproject/stdlib_my_version/main.cpp"
    .loc 1 4 0
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov eax, ecx
    mov ecx, r8d
    mov BYTE PTR [rbp-4], dil
    mov BYTE PTR [rbp-8], sil
    mov BYTE PTR [rbp-12], dl
    mov BYTE PTR [rbp-16], al
    mov BYTE PTR [rbp-20], cl
    .loc 1 5 0
 
        ; а вот те самые сравнения, о которых ты так кричал
 
    cmp BYTE PTR [rbp-4], 0
    je  .L2
    .loc 1 5 0 is_stmt 0 discriminator 1
    cmp BYTE PTR [rbp-8], 0
    je  .L2 ; если значение по адресу rbp-8 равно 0, бежим на .L2, которая возвращает false
    .loc 1 5 0 discriminator 3
    cmp BYTE PTR [rbp-12], 0
    je  .L2
    .loc 1 5 0 discriminator 5
    cmp BYTE PTR [rbp-16], 0
    je  .L2
    .loc 1 5 0 discriminator 7
    cmp BYTE PTR [rbp-20], 0
    je  .L2
    .loc 1 5 0 discriminator 9
    mov eax, 1
    jmp .L3
.L2:
    .loc 1 5 0 discriminator 10
    mov eax, 0 ; вернуть false
.L3:
    .loc 1 6 0 is_stmt 1 discriminator 12
    pop rbp ; снимаем со стека регистр базы
    .cfi_def_cfa 7, 8
    ret ; и возвращаемся в точку вызова
    .cfi_endproc
Добавлено через 4 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
bool func(bool a1, bool a2, bool a3, bool a4, bool a5)
{
    if(a1)
    if(a2)
    if(a3)
    if(a4)
    if(a5)
        return true;
 
    return false;
}
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
_Z4funcbbbbb:
.LFB0:
    .file 1 "/home/mint/Develop/cbproject/stdlib_my_version/main.cpp"
    .loc 1 4 0
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov eax, ecx
    mov ecx, r8d
    mov BYTE PTR [rbp-4], dil
    mov BYTE PTR [rbp-8], sil
    mov BYTE PTR [rbp-12], dl
    mov BYTE PTR [rbp-16], al
    mov BYTE PTR [rbp-20], cl
 
       ; ну и где твоя оптимизация?
 
 
    .loc 1 5 0
    cmp BYTE PTR [rbp-4], 0
    je  .L2
    .loc 1 6 0
    cmp BYTE PTR [rbp-8], 0
    je  .L2
    .loc 1 7 0
    cmp BYTE PTR [rbp-12], 0
    je  .L2
    .loc 1 8 0
    cmp BYTE PTR [rbp-16], 0
    je  .L2
    .loc 1 9 0
    cmp BYTE PTR [rbp-20], 0
    je  .L2
    .loc 1 10 0
    mov eax, 1
    jmp .L3
.L2:
    .loc 1 12 0
    mov eax, 0
.L3:
    .loc 1 13 0
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
4
Заблокирован
24.07.2016, 10:13 19
Один мой знакомый программер, тоже любил полагаться на точки следования, он не знал об волатильных переменных и многопоточности и в конечном счёте это его згубило.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
 
 
bool func(bool bFlag = false){
    cout<<"\t->func1"<<endl;
    return bFlag ;
}
 
void proc(int  * p){
    if( p )
    *p = 0;
}
 
int calc(int a, int b) throw (const char *){
    if( b == 0 )
        throw "div on zero";
    return a / b;
}
 
 
int main(){
    volatile int p = 1;
    bool result  = false;
    int * ptr    = (int *)(&p);
    thread t(proc, ptr);
    try{
    if
    (
        (result = p != 0), t.detach(), this_thread::sleep_for (chrono::seconds(5)), result&&
        func(calc(1, p))  
    )
        cout<<"true "<<endl;
    else
        cout<<"false"<<endl;
    }
    catch(const char * msg){
        cout<<msg<<endl;
    }
    cin.get();
    return 0;
}
http://ideone.com/Q4AS29

Добавлено через 5 минут
ASCII, прочти о соглашении о вызове для функций(когда идёт слева направо а когда наоброт) и запихни вместо своих булевых флагов параметрами результаты зависимых логических выражений, подумаешь сам, ты ж асм умеешь выдирать
Хотя что мне тут говорить о чём и главное с кем?

Не по теме:

Для тех кто в танке : В теме говорилось о клике мышью и ренедере, что уже намекает на многопоточность, за время проверки координаты мыши могут вообще измениться(включая и сам рендерер). В данной задаче сложновато приклеить предложенную мной выше синтетическую вполне понятную точку следования, но в реальной жизни это часто себя оправдывает. Ладно напостили шлака, асм выдрали, слов нет, я пошёл дальше...

0
586 / 395 / 147
Регистрация: 01.10.2015
Сообщений: 1,162
24.07.2016, 10:30 20

Не по теме:

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



Цитата Сообщение от Unknownx Посмотреть сообщение
о клике мышью и ренедере, что уже намекает на многопоточность
Да ни на что это не намекает
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.07.2016, 10:30

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Метод, проверяющий можно ли разделить массив так, чтобы сумма элементов в обоих частях была равной
Реализуйте метод, который принимает на вход массив целых чисел (длиной 2 или более) и возвращает...

Спасите мой мозг. Задача 3) Написать метод проверяющий является ли строка поллиндромом(типа arrttrra). Задание
Уважаемые форумчане, помогите пожалуйста написать решения задач на лекцию на сегодня до 10 утра.....

Far Cry 1: оптимален ли конфиг?
Хочу поиграть в Far Cry 1 на старичке: Celeron D 2.5 GHZ SiS Mirage Graphics 32MB 1.5 GB RAM ...

Очищение списка БД - оптимален ли приведенный код
Добрий день, нуждаюсь в помощи. У меня есть список DataBase, с которого я должен удалять...


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

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

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