visual Невозможно создать экземпляр абстрактного класса

(Я довольно новичок в C ++, так что, надеюсь, это просто ошибка новичка)

У меня проблемы в моем коде, где у меня есть класс «Player», которому нужен ряд атрибутов, которые я пытаюсь дать ему, используя абстрактные классы как таковые:

//player.h

class Player : public IUpdate, public IPositionable, public IMoveable, public IDrawable
{
public:
Player(void);
SDL_Rect get_position();
void move(Uint32 dTime);
void update(Uint32 dTime);
void show(SDL_Surface* destination);
~Player(void);
private:
SDL_Surface texture;
int x, y;
};

И я переопределяю чисто виртуальные функции как таковые:

//Player.cpp
Player::Player(void)
{
}

SDL_Rect Player::get_position()
{
SDL_Rect rect;
rect.h = 0;
return rect;
}

void Player::move(Uint32 dTime)
{

}

void Player::update(Uint32 dTime)
{
move(dTime);
}

void Player::show(SDL_Surface* destination)
{
apply_surface(x, y, &texture, destination, NULL);
}

Player::~Player(void)
{
}

Однако я продолжаю получать ошибку компиляции: C2259: 'Player' : cannot instantiate abstract class

Насколько я вижу, чисто виртуальные функции должны быть переопределены, что, как сказали мне мои поиски в Google, сделало бы Player неабстрактным, хотя Player по-прежнему выглядит абстрактным.

РЕДАКТИРОВАТЬ:
Чистые виртуальные функции:

class IPositionable
{
public:
virtual SDL_Rect get_position() = 0;
private:
int posX, posY;
};

class IUpdate
{
public:
virtual void update (Uint32 dTime) = 0;
};

class IMoveable
{
public:
int velX, velY;
virtual void move(Uint32 dTime) = 0;
};

class IDrawable
{
public:
virtual void show() = 0;
private:
SDL_Surface texture;
};

class IHitbox
{
virtual void check_collsion() = 0;
};

class IAnimated
{
virtual void next_frame() = 0;
int state, frame;
int rows, columns;
};

2

Решение

Ваша проблема здесь:

class IDrawable
{
public:
virtual void show() = 0;
};

void Player::show(SDL_Surface* destination)
{
apply_surface(x, y, &texture, destination, NULL);
}

Обратите внимание, что Player::show(SDL_Surface* destination) не переопределяет чисто виртуальный метод IDrawable::show(),
Чтобы переопределить метод, вам нужно точно определить сигнатуру функции в производном классе (разрешены только ко-вариантные типы возврата)
Сейчас у вас есть метод с именем show() в производном классе, который шкуры метод по имени show() в Базовом классе это не отменяет это. Поскольку вы не предоставляете определения для всех чисто виртуальных функций вашего класса Player Компилятор справедливо говорит вам, что это абстрактный класс.

4

Другие решения

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

struct base {
virtual void foo(double d) = 0;
};

struct derived: base {
// does not override base::foo; possible subtle error
void foo(int i);
}

Возможно, вы захотите еще раз проверить свой код, просмотрев его. Если бы вы использовали C ++ 11, вы бы могли пометить свои функции override ловить такие ошибки.

1

Абстрактный класс является абстрактным — то есть что-то не определено, а просто объявлено.

Вы должны определить все эти методы. Поскольку у меня нет объявлений для этих классов, я не могу посоветовать вам, какие методы вам не хватает.

0

В C ++ функция не является виртуальной, если она специально не написана:

virtual void move(Uint32 dTime);

чисто виртуальная функция определяется так:

virtual void move(Uint32 dTime) = 0;

«Интерфейсы», от которых вы наследуете (обратите внимание, что это множественное наследование.. C ++ не отличается интерфейсами от классов) имеет чисто виртуальные функции, которые вы не реализовали, что делает ваш класс абстрактным.

0

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

Я ожидаю, что компилятор скажет вам, какая функция все еще не переопределена, что-то вроде (vc9):

C2259: 'Player' : cannot instantiate abstract class
due to following members:
'void IUpdate::update(void)' : is abstract
virtualclass.cpp(3) : see declaration of 'IUpdate::update'

Если ваш компилятор не сообщил об этом, вы можете проверить, удалив унаследованный интерфейс один за другим.

0
По вопросам рекламы [email protected]