Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 19.12.2009
Сообщений: 14

Подставить неизвестный класс в функцию

21.05.2010, 10:26. Показов 1391. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть базовый класс Human, от него наследованы Mage, Paladin

как передать заранее неизвестный класс в перегруженную функцию battle(player, enemy)?

т.е.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch(select):
 case(1):
  Human Player("Вася", 100, 20);
  break;
 case(2):
  Mage Player ("Петя", 100, 30);
  break;
 
switch(select)
  case(1):
  Human Enemy("Жора", 100, 20);
  break;
 case(2):
  Mage Enemy ("Саша", 100, 30);
  break;
 
Battle(human, enemy); // - как задекларировать переменные?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.05.2010, 10:26
Ответы с готовыми решениями:

Можно ли унаследовать заранее неизвестный класс?
Всем привет! Помогите, пожалуйста разобраться с наследованием в C++. Я пока новичок, хочу написать нейронную сеть. Столкнулся с...

Функция должна принимать указатель на неизвестный класс?
Ситуация: 1.срр 2.срр 1.h 2.h В 1.h создан класс myClass, в 2.h описание функции, которая должна принимать указатель на...

подставить функцию
Задание: Значение аргумента х изменяется от а до b с шагом h. Для каждого х найдите значение функции Y(x), суммы S(x) и...

7
 Аватар для nec
15 / 15 / 5
Регистрация: 19.05.2010
Сообщений: 41
21.05.2010, 11:23
Вопрос не совсем корректен. Если функция перегружена, то это означает, что имеется несколько вариантов данной функции с одинаковым именем, но разными типами аргументов. Компилятор на основе типов аргументов решает, какую функцию вызывать.

И еще, код не похож на сишный =))

Если мой телепат правильно догадался и наследники Human просто реализуют разные типы поведения не изменяя интерфейса базового класса, то прототип функции будет примерно такой:

<возвращаемый_тип> battle(Human &human, Human &enemy);
0
332 / 247 / 32
Регистрация: 13.12.2009
Сообщений: 589
21.05.2010, 11:27
передавать указатели на объекты
C++
1
Battle(Human *human, Human *enemy);
0
0 / 0 / 0
Регистрация: 19.12.2009
Сообщений: 14
21.05.2010, 11:59  [ТС]
nec, телепатия вас не подводит, код не сишный, а моя импровизация, потому что исходники остались дома и я просто выложил то, что в памяти осталось.

А если передавать указатели на объект, то у меня было так, что Mage становился Human, т.е. не использовал методы, которые были объявлены в этом классе.

Вообще интересует вопрос - как передать неизвестно что в функцию.

На PHP это было бы так:

PHP
1
2
3
4
5
6
7
8
var p1: Object; var p2: Object;
switch ()
case 1 : p1 = new Human()
case 2 : p1 = new Mag();
switch()
case 1: p2 = new Human();
case 2: p2 = new Mag();
battle(p1, p2)
0
332 / 247 / 32
Регистрация: 13.12.2009
Сообщений: 589
21.05.2010, 12:30
Цитата Сообщение от WoodyArt Посмотреть сообщение
А если передавать указатели на объект, то у меня было так, что Mage становился Human, т.е. не использовал методы, которые были объявлены в этом классе.
C++
1
2
3
4
void Battle(Human *human, Human *enemy)
{
    dynamic_cast<Mage *>(human)->...
}
Цитата Сообщение от WoodyArt Посмотреть сообщение
как передать неизвестно что в функцию.
как сделать что-то, если не знаешь что делать?

Добавлено через 21 минуту
кажется я понял о чём речь, мой вариант не то
0
16 / 16 / 2
Регистрация: 31.07.2009
Сообщений: 54
21.05.2010, 14:44
имхо, Тут разница видать в том, что в ПХП среда исполнения помнит чем был объект
до того как прошел в функцию через аргумент типа Object. В С++ этого нет,
если привел одно к другому, то чем это было раньше вспоминай сам и приводи
к чему нужно. Т.е. по идее вам надо в Human добавить какой-то опознавательный знак.
Например, что-то типа такого(Если я правильно понял Вашу задумку) -

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
#include "stdafx.h"
 
class IMage
{
public:
    virtual void SomeMageActions() = 0;
};
 
class IPaladin
{
public:
    virtual void SomePaladinActions() = 0;
};
 
class Human 
{
public:
    enum TType
        {
            EMage, EPaladin
        };
TType Who;
IMage* GetMageInterface() { return (IMage*)this; } 
IPaladin* GetPaladinInterface() { return (IPaladin*)this; }
};
 
class Mage : Human, IMage
{
public:
    void SomeMageActions() {}
};
 
class Paladin : Human, IPaladin
{
public:
    void SomePaladinActions() {}
};
 
void Battle(Human* Player, Human* Enemy)
{
    switch(Player->Who)
    {
    case Human::EMage:
        Player->GetMageInterface()->SomeMageActions();
        break;
    case Human::EPaladin:
        Player->GetPaladinInterface()->SomePaladinActions();
        break;
    }
    ///И тоже самое для Enemy
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    Mage M;
    Paladin P;
    Battle((Human*)&M, (Human*)&P);
    return 0;
}
Хотя мож это и не самый лучший вариант, но больше ничего в голову не приходит.

А передавать неизвестно что можно ещё и так -

void DoSomething(void* aUnknown);

Но это, и то что будет дальше в такой функции, конечно злое колдунство.

Добавлено через 36 минут
А хотя и это всё не верно, потом исправлю.
1
332 / 247 / 32
Регистрация: 13.12.2009
Сообщений: 589
21.05.2010, 14:48
Цитата Сообщение от Skoi Посмотреть сообщение
class Human
{
public:
enum TType
{
EMage, EPaladin
};
TType Who;
IMage* GetMageInterface() { return (IMage*)this; }
IPaladin* GetPaladinInterface() { return (IPaladin*)this; }
};
получается базовый класс зависит от производных

предложу свой вариант (тоже без бубна не обошлось)
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
class A
{
    public:
        virtual ~A(void) {};
};
 
class B : public A{};
class C : public A{};
 
void F (B *p1, B *p2)
{
    cout << "B" << endl;
}
void F (C *p1, C *p2)
{
    cout << "C" << endl;
}
void F (A *p1, A *p2)
{
    B *is_b = dynamic_cast<B*>(p1);
    if (is_b)
        F (dynamic_cast<B*>(p1), dynamic_cast<B*>(p2));
    else
        F (dynamic_cast<C*>(p1), dynamic_cast<C*>(p2));
}
 
int main()
{
    A *p1, *p2, *p3, *p4;
    p1 = new B;
    p2 = new B;
    p3 = new C;
    p4 = new C;
 
    F (p1, p2);
    F (p3, p4);
 
    delete p1;
    delete p2;
    delete p3;
    delete p4;
    return 0;
}
0
 Аватар для nec
15 / 15 / 5
Регистрация: 19.05.2010
Сообщений: 41
21.05.2010, 15:50
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
#include <iostream>
#include <string>
 
using namespace std;
 
class Human
{
   public:
      virtual void hit_the_enemy(Human &enemy);
      string get_name() { return human_name; };
      Human(string name);
 
   protected:
      string human_name;
};
 
class Paladin : public Human
{
   public:
      virtual void hit_the_enemy(Human &enemy);
      Paladin(string name);
 
};
 
class Mage : public Human
{
   public:
      virtual void hit_the_enemy(Human &enemy);
      Mage(string name);
 
};
 
 
Human::Human(string name): human_name(name)
{
}
 
 
Paladin::Paladin(string name): Human(name)
{
}
 
 
Mage::Mage(string name): Human(name)
{
}
 
void Human::hit_the_enemy(Human &enemy)
{
   cout << "human " << human_name.c_str() << " hits " << enemy.get_name() << endl;
   return;
}
 
void Paladin::hit_the_enemy(Human &enemy)
{
   cout << "paladin " << human_name.c_str() << " prays for " << enemy.get_name() << endl;
   return;
}
 
void Mage::hit_the_enemy(Human &enemy)
{
   cout << "mage " << human_name.c_str() << " booms " << enemy.get_name() << endl;
   return;
}
 
void battle(Human &human, Human &enemy)
{
   human.hit_the_enemy(enemy);
   enemy.hit_the_enemy(human);
   cout << endl;
   return;
}
 
int main(int argc, char **argv)
{
   Human h("Pit");
   Paladin p("Roger");
   Mage m("Elph");
 
   battle(h, p);
   battle(p, m);
   battle(m, h);
 
   return 0;
}
Смысл в том, чтобы у класса-родителя объявить замещаемые методы виртуальными.
Тогда при смене типа указателя данные о выполняемых методах не потеряются.

http://ru.wikipedia.org/wiki/%... 0%BE%D0%B4
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.05.2010, 15:50
Помогаю со студенческими работами здесь

Добавить неизвестный коэф. в передаточную функцию
Доброго времени суток, помогите пожалуйста добавить в передаточную функцию W=tf(...) в числитель неизвестный коэф. Kmp. Чтобы результат...

Не получается подставить выражение в функцию
Выдает ошибку при подстановке

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

Как в функцию подставить переменную?
Приветствую! Вот так работает: &lt;?php query_posts(cat=33&amp;posts_per_page=1000&amp;orderby=title&amp;order=ASC'); ?&gt; а вот так нет: ...

Подставить переменные в функцию вместо значений
MessageBoxA(0, &quot;1&quot;, &quot;Ошибка&quot;, MB_OK); Как сделать так чтобы вместо &quot;1&quot; и &quot;Ошибка&quot; были переменные


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru