Форум программистов, компьютерный форум CyberForum.ru

подставить неизвестный класс в функцию - C++

Восстановить пароль Регистрация
 
WoodyArt
0 / 0 / 0
Регистрация: 19.12.2009
Сообщений: 14
21.05.2010, 10:26     подставить неизвестный класс в функцию #1
Есть базовый класс 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); // - как задекларировать переменные?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nec
 Аватар для nec
14 / 14 / 2
Регистрация: 19.05.2010
Сообщений: 41
21.05.2010, 11:23     подставить неизвестный класс в функцию #2
Вопрос не совсем корректен. Если функция перегружена, то это означает, что имеется несколько вариантов данной функции с одинаковым именем, но разными типами аргументов. Компилятор на основе типов аргументов решает, какую функцию вызывать.

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

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

<возвращаемый_тип> battle(Human &human, Human &enemy);
Roma_F
331 / 246 / 5
Регистрация: 13.12.2009
Сообщений: 589
21.05.2010, 11:27     подставить неизвестный класс в функцию #3
передавать указатели на объекты
C++
1
Battle(Human *human, Human *enemy);
WoodyArt
0 / 0 / 0
Регистрация: 19.12.2009
Сообщений: 14
21.05.2010, 11:59  [ТС]     подставить неизвестный класс в функцию #4
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)
Roma_F
331 / 246 / 5
Регистрация: 13.12.2009
Сообщений: 589
21.05.2010, 12:30     подставить неизвестный класс в функцию #5
Цитата Сообщение от WoodyArt Посмотреть сообщение
А если передавать указатели на объект, то у меня было так, что Mage становился Human, т.е. не использовал методы, которые были объявлены в этом классе.
C++
1
2
3
4
void Battle(Human *human, Human *enemy)
{
    dynamic_cast<Mage *>(human)->...
}
Цитата Сообщение от WoodyArt Посмотреть сообщение
как передать неизвестно что в функцию.
как сделать что-то, если не знаешь что делать?

Добавлено через 21 минуту
кажется я понял о чём речь, мой вариант не то
Skoi
16 / 16 / 1
Регистрация: 31.07.2009
Сообщений: 54
21.05.2010, 14:44     подставить неизвестный класс в функцию #6
имхо, Тут разница видать в том, что в ПХП среда исполнения помнит чем был объект
до того как прошел в функцию через аргумент типа 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 минут
А хотя и это всё не верно, потом исправлю.
Roma_F
331 / 246 / 5
Регистрация: 13.12.2009
Сообщений: 589
21.05.2010, 14:48     подставить неизвестный класс в функцию #7
Цитата Сообщение от 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;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.05.2010, 15:50     подставить неизвестный класс в функцию
Еще ссылки по теме:

Указатель на функцию и функциональный класс C++
FindFirstFileW. Как подставить значение переменной типа string в функцию? C++
Передать класс в функцию C++

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

Или воспользуйтесь поиском по форуму:
nec
 Аватар для nec
14 / 14 / 2
Регистрация: 19.05.2010
Сообщений: 41
21.05.2010, 15:50     подставить неизвестный класс в функцию #8
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/%D0%92%...82%D0%BE%D0%B4
Yandex
Объявления
21.05.2010, 15:50     подставить неизвестный класс в функцию
Ответ Создать тему
Опции темы

Текущее время: 21:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru