Я пытаюсь закодировать серию js super-mario с отличного канала YouTube «метод метамфетамина» на С++ и SDL2.
Теперь я застрял на Эпизоде 04 - https://thewikihow.com/video_1rBOUyRGQuU
Я пытаюсь создать класс Entity, который имеет вектор класса Trait. Я хочу создать много разных классов, которые наследуются от Trait и сохранят их в векторе. Я хочу вызвать функцию обновления подклассов, а не исходную функцию обновления признаков.
// -- Entity.h -----------------------------------
class Entity {
private:
Vec2 vel;
std::vector<Trait*> traits;
public:
Vec2 pos;
// Constructor & Destructor
Entity(void);
~Entity(void);
void addTrait(Trait* nTrait);
void update();
};
// -- Entity.cpp -----------------------------------
void Entity::addTrait(Trait* newTrait) {
this->traits.push_back( newTrait );
}
void Entity::update() {
for ( Trait* trait : this->traits ) {
trait->update( );
}
}
// -- Trait.h -----------------------------------
class Trait {
private:
std::string name;
public:
// Constructor & Destructor
Trait(std::string aname );
~Trait(void);
void update( void );
};
// -- Trait.cpp -----------------------------------
void Trait::update( ) {
printf("Trait update\n");
}
И подклассы Velocity.h от Trait
// -- Velocity.h -----------------------------------
class Velocity : public Trait {
private:
public:
// Constructor & Destructor
Velocity(std::string aname);
~Velocity(void);
void update(Entity *entity);
};
// -- Velocity.cpp -----------------------------------
void Velocity::update(Entity *entity ) {
printf("Velocity update\n");
entity->setPos(0, 0);
}
Я пробовал много разных версий и получал разные ошибки. Теперь у меня это работает, но когда я добавляю свойство скорости к объекту и вызываю метод обновления объекта (который перебирает все признаки), только функция обновления вызывается из родительского класса признаков (который печатает «Обновление признаков» и не "обновление скорости").
main.cpp
Entity *mario = new Entity();
mario->setPos( 64, 180 );
mario->setVel( 2, -2 );
Velocity* velTrait = new Velocity("velocity");
mario->addTrait(velTrait);
mario->update();
И второй вопрос заключается в том, что я хочу дать функции обновления скорости указатель на объект, чтобы я мог изменить положение объекта и т. д.
@xpnimi Рассматривали ли вы на самом деле учусь C++ (это займет пару лет), а не просто следуя случайным руководствам на YouTube?
@JesperJuhl Я пытаюсь изучать C++ на стороне, и я думаю, что это хорошее упражнение для переноса кода с одного языка на другой - это вовсе не случайное видео yt. Но все равно спасибо.





I want to create many different classes which inherit from
Traitand store them in the vector. I want to call the subclasses update function and not the originalTraitupdate function.
Чтобы получить то, что вы хотите, используйте метод virtual:
virtual void update( void );
Для получения более подробной информации я предлагаю вам изучить полиморфизм и виртуальные функции.
Да, я пробовал это, но куда именно идет ключевое слово virtual? только для обновления Trait.h??
если я добавлю virtual к функции обновления признаков, функция обновления скорости все равно не будет вызываться.
Чтобы это заработало, функция обновления скорости должна быть объявлена так же, как и функция скорости трейтов.
@xpnimi да, это так. А в C++11 и более поздних версиях вы можете (и должны) пометить метод класса-потомка как override, чтобы позволить компилятору проверить, действительно ли метод-потомок переопределяет метод базового класса или нет: void update(void) override; Без override такая проверка не выполняется. , вот почему вы пропустили эту ошибку, когда впервые добавили virtual
@RemyLebeau, как я могу передать сущность любой черте вектора черт внутри функционального цикла обновления сущности? Если я добавлю Entity.h в Trait.h, я получу довольно много ошибок, и я думаю, что это конфликт, потому что оба класса ссылаются на себя...
@xpnimi Вам действительно придется изменить метод Trait::update(), чтобы он принимал Entity* в качестве входных данных, чтобы Velocity::update() мог сделать то же самое. Но затем вы сталкиваетесь с классической проблемой циклических ссылок, которая решается с помощью указателей (которые у вас уже есть) и предварительные заявления (именно этого вам не хватает).
@RemyLebeau Спасибо - это очень помогло, все заработало!
Держитесь подальше от метода кристаллического метамфетамина.