Структурирование классов с множественным наследованием

Это не реальный вопрос программирования, мне просто нужен совет о том, как структурировать часть моей программы.

Программа разделена на клиентскую и серверную части. Оба имеют определенный код, включая базовые классы. Вот представление кода, с которым у меня возникли проблемы:

Общие классы:

class BaseEntity
{
public:
    virtual void EmitSound(std::string snd) {}
    virtual bool IsPlayer() {return false;}
};

class BasePlayer
    : public BaseEntity
{
public:
    bool IsPlayer() {return true;}
}

Серверные классы:

class Entity
    : public BaseEntity
{
public:
    void EmitSound(std::string snd)
    {
        // Serverside implementation
    }
}

class Player
    : public Entity,BasePlayer
{
public:
    void Kick() {}
}

Клиентские классы:

class CEntity
    : public BaseEntity
{
public:
    void EmitSound(std::string snd)
    {
        // Clientside implementation
    }
};

class CPlayer
    : public CEntity,BasePlayer
{
public:
    void SetFOV() {}
}

(Методы являются просто примерами)

Класс «Player» должен наследовать все члены как от «Entity», так и от «BasePlayer». Однако это не работает, поскольку оба имеют один и тот же родительский класс (BaseEntity).

Я мог бы, конечно, удалить наследование от «BasePlayer», но тогда я получил бы две функции «IsPlayer», каждая из которых возвращала бы что-то свое.

Я также мог бы переместить всех членов из «BasePlayer» в «Player» и «CPlayer» соответственно, но это привело бы к избыточности, которой я хотел бы избежать, и я больше не мог бы использовать один указатель для объектов любого из них. класс, сохраняя при этом доступ ко всем общим методам.

Мне не нравится ни одно из этих решений, но я не могу придумать ничего другого. Существует ли оптимальное решение этой проблемы?


person Silverlan    schedule 01.06.2013    source источник
comment
Какова цель сущности и почему Player должен наследовать от нее, а BasePlayer должен наследовать от BaseEnttity? Мне это кажется смешением разных классов, что не так, как должно быть.   -  person Mats Petersson    schedule 01.06.2013


Ответы (1)


Я вижу, что самое простое решение, которое, я думаю, решит вашу конкретную проблему, - это иметь класс BasePlayer, не наследуемый от класса BaseEntity.

класс Player получит характеристики класса BaseEntity, поскольку он наследуется от класса Entity, который наследуется от класса BaseEntity, а класс CPlayer получит характеристики класса BaseEntity, поскольку он наследуется от класса CEntity, который наследуется от класса BaseEntity.

person john.k.doe    schedule 01.06.2013
comment
Это дилемма. BasePlayer ДОЛЖЕН наследовать от BaseEntity, потому что BaseEntity определяет такие вещи, как его положение и ориентация (и многое другое). Я, вероятно, должен был сделать это более ясным в примере. - person Silverlan; 01.06.2013
comment
@Silverlan, чтобы сослаться на position и orientation, по-прежнему нет необходимости наследовать BasePlayer от BaseEntity. в случае, когда вы уже ссылаетесь на объекты Player/CPlayer, вы получите возможность ссылаться на эти position и orientation бесплатно, поскольку вы будете наследоваться от BaseEntity через Entity и CEntity, а в случае, когда вам нужно ссылаться на них независимо от типа BasePlayer, а затем ссылаться на них напрямую как на объекты BaseEntity… что в любом случае будет более понятной и подходящей ссылкой на класс, определяющий position и orientation. - person john.k.doe; 02.06.2013