Обходной путь для интерфейса - PullRequest
0 голосов
/ 18 октября 2011

В C ++, как я могу объявить интерфейс s.t. Я могу использовать его, как показано ниже:

/** Enemy "Interface" */
Class Enemy {
    Enemy();
    virtual ~Enemy();
    virtual void doStuff() = 0;
};

/** Enemy of type 1 */
Class Enemy_type1 : public Enemy {
    Enemy_type1();
    virtual ~Enemy_type1();
    virtual void doStuff() {
        // different for every type of enemy
    }
};

/** Add an enemy to EnemyManager */
void EnemyManager::addEnemy(Enemy * e) {
    this->enemies.push_back(*e); // declared as vector<Enemy> enemies;
}

Ответы [ 2 ]

5 голосов
/ 18 октября 2011

Во-первых, вам нужно (или, по крайней мере, захотеть) сделать функции, которые составляют ваш интерфейс общедоступными:

class Enemy {
public:
    Enemy();
    virtual ~Enemy();
    virtual void doStuff() = 0;
};

Тогда вы будете наследовать его (C ++ не имеет ")интерфейсы "и" классы "как отдельные понятия).

class Emeny_type1 : public Enemy { 
    // ...
};

Наконец, поскольку это полиморфные типы, вам нужно будет создать коллекцию указателей на врагов, а не реальных объектов врага:

void EnemyManager::addEnemy(Enemy const *e) { 
    enemies.push_back(e);
}

Это поднимает проблемы времени жизни и владения объектом (которые в основном не являются проблемами в Java).Когда вы добавляете предмет в коллекцию, вам нужно убедиться, что он не будет уничтожен до тех пор, пока вы собираетесь его использовать, а уничтожен, как только закончите с ним (например, когда враг побежден,Вы могли бы хотеть удалить это).Вам нужно решить, собирается ли EnemyManager удалять врагов, которые больше не нужны, или какой-либо другой код.Если EnemyManager собирается удалить их, вам может потребоваться (или вы хотите) добавить функцию clone в интерфейс Enemy, чтобы она получала копию объекта, добавляемого в коллекцию.

Редактировать:Исходя из вашего комментария, вы не совсем уверены, как использовать «интерфейс» указателя, который вы сохранили в своей коллекции.К счастью, это довольно просто, примерно так:

for (int i=0; i<enemies.size(); i++)
    enemies[i]->doStuff();
0 голосов
/ 18 октября 2011
/* Enemy Interface (Abstract Base Class)
   This goes in a header, say Enemy.hpp
 */
class Enemy {
public: // note default access is private in classes
    Enemy();
    virtual ~Enemy();
    virtual void doStuff() = 0;
};

/* Add an enemy to EnemyManager.
   The interface is a type, and is known!
   It doesn't need to know anything about the subclasses
   which implement the interface.
 */
void EnemyManager::addEnemy(Enemy * e) {
    this->enemies.push_back(*e); // vector of Enemy POINTERS
}

/* Enemy of type 1.
   This would go in say Enemy1.hpp - it depends on Enemy.hpp,
   but EnemyManager doesn't need to know anything about this.
 */
Class Enemy_type1: public Enemy {
public:
    Enemy_type1();
    virtual ~Enemy_type1();
    virtual void doStuff();
};

/* ... and in a .cpp file somewhere ... */
Enemy_type1::Enemy_type1() : Enemy()
{
   // this is redundant unless you have some work for it to do
}

Enemy_type1::~Enemy_type1()
{
}

void Enemy_type1::doStuff()
{
  // do your stuff here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...