С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
dailydose
overmind
410 / 147 / 41
Регистрация: 21.07.2016
Сообщений: 676
#1

Перегрузка внутри класса - C++

19.08.2016, 07:57. Просмотров 451. Ответов 20
Метки нет (Все метки)

Есть класс Points, который использует обычные стандартные функции. Здесь для примера написал две функции(работают со значениями переменных по ссылке) increaseValue, increaseValue, чтобы проще было отобразить суть, на самом деле эти я пользуюсь другими функциями.
C++
1
2
3
4
5
6
7
8
9
10
template<typename T>
void increaseValue(T& value)
{
    value++;
}
template<typename T>
void decreaseValue(T& value)
{
    value--;
}
Для удобства работы с полями этого класса сделал перегрузку присваивания, чтобы не было такого:
C++
1
2
3
4
if (this->type == "Float")
    this->value.f = newValue;
else
    this->value.i = newValue;
Вместо этого можно использовать упрощенную запись:
C++
1
*this = newValue
и в завимости от того какого типа переменная newValue запишется значение в this->value.i или же в this->value.f
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Points
{
public:
    std::string type;
    union
    {
        int i;
        float f;
    } value;
 
    void readFloatValuesFromFile();
    void readIntegerValuesFromFile();
    void doSomething();
 
private:
    template<typename T>
    Points& operator=(T newValue);
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void Points::readFloatValuesFromFile()
{
    this->type = "Float";
    *this = 250.5;
}
void Points::readIntegerValuesFromFile()
{
    this->type = "Integer";
    *this = 100;
}
 
template<typename T>
Points& Points::operator=(T newValue)
{
    if (this->type == "Float")
        this->value.f = newValue;
    else
        this->value.i = newValue;
 
    return *this;
}
Теперь собственно вопрос можно ли сделать такую же перегрузку для этого кода?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Points::doSomething()
{
    if(this->type == "Float")
        increaseValue(this->value.f);
    else
        increaseValue(this->value.i);
 
    Sleep(500);
 
    if (this->type == "Float")
        decreaseValue(this->value.f);
    else
        decreaseValue(this->value.i);
}
вот в это
C++
1
2
3
4
5
6
7
8
void Points::doSomething()
{
    increaseValue(this);
 
    Sleep(500);
 
    decreaseValue(this);
}
Вряд ли в C++ есть подобная перегрузка. В голову пришла идея использовать геттер:
C++
1
2
3
4
5
6
7
8
void Points::doSomething()
{
    increaseValue(getValue());
 
    Sleep(500);
 
    decreaseValue(getValue());
}
Но тогда вопрос в том как определить этот метод?
C++
1
2
3
4
5
6
/* ??type?? */ Points::getValue()
{
    if (this->type == "Float")
        return this->value.f;
    return this->value.i;
}
Какой должен быть тип возвращаемого значения? Eсли этот метод возвращает float или int в зависимости от значения std::string type
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.08.2016, 07:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Перегрузка внутри класса (C++):

Перегрузка внутри класса - C++
Как описывается перегрузка внутри класса и вне его?

Перегрузка оператора >> для дочернего класса от базового виртуального класса - C++
Доброго вам времени суток! Программирую на С++ не давно, в связи с отсутствием должного времени на поиск ответа в глубинах учебников,...

Создать объект внутри класса, который может вызывать функцию этого класса - C++
Ребята помогите уже несколько дней мучаюсь. Хочу сделать программу в консоле демонстрации работы лифта в здании 2 этажа. Сделал класс...

delete внутри класса для самого класса - C++
Доброго времени суток, пишу программу для работы с матрицами. По условию дали лишь несколько библиотек, ни векторов ни cstdio. Для...

Заполнение вектора класса внутри самого класса - C++
class A { private: int a; public: A() { a = 0; }; A get(vector &lt;A&gt;* vec)

BST дерево. Инициализация класса внутри класса - C++
Здравствуйте, нужно реализовать класс дерева бинарного поиска с использованием итератора. Возник вопрос, как инициализировать через...

20
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
19.08.2016, 18:12 #16
dailydose, еще раз повторю - работай с интерфейсами. определи задачу, разработай для задачи интерфейсы, потом реализуй их. и все получится.
Сначала определи задачу, четко. Потом пиши код. Не наоборот.

Добавлено через 3 минуты
Цитата Сообщение от dailydose Посмотреть сообщение
Мне же в конечном итоге нужно
Вот и определи себе, какие у тебя будут операции с этими объектами, и спроектируй для них интерфейсы. Засунешь их в базовый класс.
Можешь в псевдокоде, написать для себя порядок работы не привязываясь к конкретному типу переменной. То что получится, и будет основой абстрактного интерфейса.
Пока ты мыслишь категориями конкретного типа, ничего не выйдет
1
dailydose
overmind
410 / 147 / 41
Регистрация: 21.07.2016
Сообщений: 676
19.08.2016, 18:16  [ТС] #17
Цитата Сообщение от DrOffset Посмотреть сообщение
Хочешь выводить на экран значения
перегрузку для вывода уже нашёл в интернете #post9468603
C++
1
2
3
4
5
6
7
std::ostream & operator<<(std::ostream & _stream, Points const & p)
{
    if (this->type == "Float")
        return _stream << p.f;
    else
        return _stream << p.i;
}
Цитата Сообщение от DrOffset Посмотреть сообщение
Сформулируй задачу.
Хочу перегрузить/сделать аналог перегрузки для удобства
чтобы записи вида
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
bool Game::playerIsDead()
{
    ptr.health = getPointer(cfg->health.module, cfg->health.address, cfg->health.offsets, cfg->health.count);
 
    if (cfg->health.type == "Float")
    {
        ReadProcessMemory(hProc, (LPVOID)ptr.health, &health.f, cfg->health.size, NULL);
        return health.f < 0.1 || health.f > cfg->maxHealth.value.f;
    }
 
    ReadProcessMemory(hProc, (LPVOID)ptr.health, &health.i, cfg->health.size, NULL);
    return health.i < 1 || health.i > cfg->maxHealth.value.i;
}
сократить до
C++
1
2
3
4
5
6
bool Game::playerIsDead()
{
    ptr.health = getPointer(cfg->health.module, cfg->health.address, cfg->health.offsets, cfg->health.count);
    ReadProcessMemory(hProc, (LPVOID)ptr.health, &health, cfg->health.size, NULL);
    return health < 1 || health > cfg->maxHealth.value;
}
и
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Game::addData(types& value, Config::ammount& ammount, Config::entrys& entry, DWORD_PTR& ptr)
{
    ptr = getPointer(entry.module, entry.address, entry.offsets, entry.count);
    if (entry.type == "Float")
    {
        ReadProcessMemory(hProc, (LPVOID)ptr, &value.f, entry.size, NULL);
        value.f += ammount.value.f;
        WriteProcessMemory(hProc, (LPVOID)ptr, &value.f, entry.size, NULL);
    }
    else
    {
        ReadProcessMemory(hProc, (LPVOID)ptr, &value.i, entry.size, NULL);
        value.i += ammount.value.i;
        WriteProcessMemory(hProc, (LPVOID)ptr, &value.i, entry.size, NULL);
    }
}
соответственно в
C++
1
2
3
4
5
6
7
void Game::addData(types& value, Config::ammount& ammount, Config::entrys& entry, DWORD_PTR& ptr)
{
    ptr = getPointer(entry.module, entry.address, entry.offsets, entry.count);
    ReadProcessMemory(hProc, (LPVOID)ptr, &value, entry.size, NULL);
    value += ammount.value;
    WriteProcessMemory(hProc, (LPVOID)ptr, &value, entry.size, NULL);
}
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
19.08.2016, 18:23 #18
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от dailydose Посмотреть сообщение
перегрузку для вывода уже нашёл в интернете
Она для данного способа не подходит.

Цитата Сообщение от dailydose Посмотреть сообщение
сократить до
В данном случае это должно выглядеть примерно так:
C++
1
2
3
4
5
6
7
8
9
bool Game::playerIsDead()
{
    return health->readMemory(*this);
/* И вот это делаешь внутри readMemory(Game & gameobj):
    ptr.health = getPointer(cfg->health.module, cfg->health.address, cfg->health.offsets, cfg->health.count);
    ReadProcessMemory(hProc, (LPVOID)ptr.health, &health, cfg->health.size, NULL);
    return health < 1 || health > cfg->maxHealth.value;
*/
}
1
dailydose
overmind
410 / 147 / 41
Регистрация: 21.07.2016
Сообщений: 676
19.08.2016, 18:36  [ТС] #19
Цитата Сообщение от DrOffset Посмотреть сообщение
Сначала определи задачу, четко. Потом пиши код. Не наоборот.
Точно подмечено. Я давным давно еще задумывался о написании трейнера, и вот только в июне руки так сказать дошли до написания. Проектированием не занимался. Со временем трейнер обростал новыми фичами, аля воспроизведение звука(sndPlaySound), вшитие этих звуков в ресурсы (.exe'шник) чтобы не таскать их рядом с самой программой, создание класса Config и чтение чит-таблиц(.CT) которые создаётся программой CheatEngine и прочие плюшки...

Цитата Сообщение от DrOffset Посмотреть сообщение
В данном случае это должно выглядеть примерно так:
C++
1
2
3
4
5
6
7
8
9
bool Game::playerIsDead()
{
    return health->readMemory(*this);
/* И вот это делаешь внутри readMemory(Game & gameobj):
    ptr.health = getPointer(cfg->health.module, cfg->health.address, cfg->health.offsets, cfg->health.count);
    ReadProcessMemory(hProc, (LPVOID)ptr.health, &health, cfg->health.size, NULL);
    return health < 1 || health > cfg->maxHealth.value;
*/
}
А это, кстати, отличная идея.

отталкиваться я так понимаю от #post9469543, да ?
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
19.08.2016, 18:45 #20
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от dailydose Посмотреть сообщение
отталкиваться я так понимаю от #post9469543, да ?
Да.
Если есть какая-то логика, перенеся которую из Game, мы нарушим инкапсуляцию, то можно воспользоваться диспетчеризацией, и вернуть управление в функцию Game, но уже с конкретным типом. Например так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Game
{
public:
    template <typename T>
    void doSomething(Point<T> & point)
    {
        // тут уже можно звать геттер у point
    }
//...........
    void doSomethingAbstract()
    {
        pBase->doSomething(*this); 
        // вызовется
        // virtual void doSomething(Game & gameobj) { gameobj.doSomething(*this); } 
        // далее в шаблонную функцию Game::doSomething<T>(Point<T> &)
    }
private:
    PointBase * pBase; 
};
Смотри, короче, по обстоятельствам.
1
dailydose
overmind
410 / 147 / 41
Регистрация: 21.07.2016
Сообщений: 676
19.08.2016, 19:15  [ТС] #21
DrOffset,
Похоже получилось, но это лишь на этом псевдокода, позже перенесу на основной код там и видно будет.

На основе предложенного тобой способа(#post9468603) подкорректировал свой код, как ты сказал
Цитата Сообщение от DrOffset Посмотреть сообщение
При этом подходе надо писать так, чтобы снаружи до него не надо было добираться.
C++
1
2
3
4
5
6
int main()
{
    Trainer trainer;
    std::cout << (int)trainer.checkPlayerIsDead() << std::endl;
    return 0;
}
C++
1
2
3
4
    bool Trainer::checkPlayerIsDead()
    {
        return health->check();
    }
C++
1
2
3
4
    bool point::check()
    {
        return value <= 0 || value > 1000;
    }
C++
1
virtual bool pointBase::check() = 0;
Здесь всё прекрасно работает
Взять всё тотже config.ini
int
100
float
250.0


то
C++
1
std::cout << (int)trainer.checkPlayerIsDead() << std::endl; //0
выводит 0, т.е. return 100<= 0 || 100 > 1000; // false

стоит только заменить в этом файле значение 100 на другое, допустим меньше либо равное нулю или наоборот больше чем 1000, то выводит 1, т.е. игрок мёртв

Добавлено через 1 минуту
полный код:
Цитата Сообщение от main.cpp
Кликните здесь для просмотра всего текста
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <windows.h>
#include <string>
#include <fstream>
#include <memory>
 
class pointBase
{
public:
    void* value;
    virtual ~pointBase() {}
    virtual bool check() = 0;
};
 
template<typename T>
class point : public pointBase
{
public:
    T value;
    point(T value)
    {
        this->value = value;
    }
    ~point() {}
 
    bool check()
    {
        return value <= 0 || value > 1000;
    }
};
 
class Trainer
{
public:
    std::unique_ptr<pointBase> health;
    std::unique_ptr<pointBase> armour;
 
    Trainer()
    {
        readFile();
    }
    ~Trainer() {}
 
    bool checkPlayerIsDead()
    {
        return health->check();
    }
private:
    void readFile();
};
 
int main()
{
    Trainer trainer;
 
    std::cout << (int)trainer.checkPlayerIsDead() << std::endl;
 
 
    return 0;
 
}
 
void Trainer::readFile()
{
    std::string buff;
    std::ifstream ini("config.ini");
 
    // [copy it for armour]
    getline(ini, buff);
    if (buff == "Float")
    {
        getline(ini, buff);
        health = std::make_unique<point<float>>(std::stof(buff));
    }
    else
    {
        getline(ini, buff);
        health = std::make_unique<point<int>>(std::stoi(buff));
    }
    // [/copy it for armour]
 
    /*
    ** paste it here:
    */
    getline(ini, buff);
    if (buff == "Float")
    {
        getline(ini, buff);
        armour = std::make_unique<point<float>>(std::stof(buff));
    }
    else
    {
        getline(ini, buff);
        armour = std::make_unique<point<int>>(std::stoi(buff));
    }
 
    ini.close();
}
0
19.08.2016, 19:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.08.2016, 19:15
Привет! Вот еще темы с ответами:

Объявление дружественного класса внутри класса - C++
class A{ friend class B{ B(A &amp;a); } } Подскажите пожалуйста, такое возможно или нет, я хотел чтобы...

Видимость экземпляра класса внутри класса - C++
Здравствуйте! Пытаюсь вывести openCV видео в QT виджете. На данный момент в слоте обновления картинки инициализирую класс cv::VideoCapture...

Методы класса внутри определения класса - C++
Все привет! Решил закрепить свои знания по C++, читаю Р.Лафоре - &quot;Объектро-ориентированное программирование в C++&quot;. В книге, на...

Инициализация класса A внутри класса B - C++
заранее извиняюсь, наверняка подобное было на одной из 1000 страниц=)... есть 2 класса //собственно первый класс class matrix ...


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

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

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