There is a base class GameObject

GameObject.h

 #pragma once #include "cocos2d.h" USING_NS_CC; class GameObject { public: GameObject(); GameObject(float x, float y, Vec2 direction); virtual ~GameObject(); virtual float getX(); virtual void setX(float value); virtual float getY(); virtual void setY(float value); virtual float getRotation(); virtual void setRotation(float value); virtual void rotateBy(float value); virtual void update(float deltaTime){}; protected: void calculateRotation(); float x; float y; float rotation; Vec2 direction; }; 

GameObject.cpp

 #include "GameObject.h" GameObject::GameObject():x(0), y(0), direction(0, 1), rotation(0) { } GameObject::GameObject(float x, float y, Vec2 direction):x(x), y(y), direction(direction), rotation(0) { } GameObject::~GameObject() { } float GameObject::getX() { return x; } void GameObject::setX(float value) { x = value; } float GameObject::getY() { return y; } void GameObject::setY(float value) { y = value; } float GameObject::getRotation() { return rotation; } void GameObject::setRotation(float value) { rotation = value; } void GameObject::rotateBy(float value) { direction.rotate(Vec2(0, 0), value); calculateRotation(); } void GameObject::calculateRotation() { rotation = MATH_RAD_TO_DEG(atan2f(direction.x, direction.y)); } 

The BulletModel class inherits from GameObject

BulletModel.h

 #pragma once #include "GameObject.h" class BulletModel: public GameObject { public: BulletModel(float x, float y, Vec2 direction); virtual ~BulletModel(); void update(float deltaTime); private: float speed; float damange; }; 

BulletModel.cpp

 #include "BulletModel.h" BulletModel::BulletModel(float x, float y, Vec2 direction):GameObject(x, y, direction) { } BulletModel::~BulletModel() { } void BulletModel::update(float deltaTime) { x += direction.x * speed * deltaTime; y += direction.y * speed * deltaTime; } 

The TankModel class TankModel inherited from Unit which is inherited from GameObject

Unit.h

 #pragma once #include "GameObject.h" class Unit: public GameObject { public: Unit(int health); virtual ~Unit(); virtual void update(float deltaTime) {}; protected: int health; }; 

Unit.cpp

 #include "Unit.h" Unit::Unit(int health):GameObject(), health(health) { } Unit::~Unit() { } 

TankModel.h

 #pragma once #include "Unit.h" class WorldModel; class TankModel: public Unit { public: TankModel(std::shared_ptr<WorldModel> world); virtual ~TankModel(); void thrust(float deltaTime); void backing(float deltaTime); void rotateLeft(float deltaTime); void rotateRight(float deltaTime); void shoot(float deltaTime); void update(float deltaTime); private: const float moveSpeed; const float rotationSpeed; std::shared_ptr<WorldModel> world; }; 

TankModel.cpp

 #include "WorldModel.h" #include "TankModel.h" #include "BulletModel.h" #include "GameScene.h" TankModel::TankModel(std::shared_ptr<WorldModel> world): Unit(100), moveSpeed(50), rotationSpeed(3), world(world) { } TankModel::~TankModel() { } void TankModel::thrust(float deltaTime) { x += direction.x * moveSpeed * deltaTime; y += direction.y * moveSpeed * deltaTime; } void TankModel::backing(float deltaTime) { x -= direction.x * moveSpeed * deltaTime; y -= direction.y * moveSpeed * deltaTime; } void TankModel::rotateLeft(float deltaTime) { rotateBy(rotationSpeed * deltaTime); } void TankModel::rotateRight(float deltaTime) { rotateBy(-rotationSpeed * deltaTime); } void TankModel::shoot(float deltaTime) { world->addBullet(x, y, direction); } void TankModel::update(float deltaTime) { } 

I create a container std::vector<std::shared_ptr<GameObject>> models;

Objects std::shared_ptr<TankModel> can be put into it, but objects std::shared_ptr<BulletModel> cannot be.

Gives an error message

 WorldModel.cpp(34): error C2664: 'void std::vector<std::shared_ptr<GameObject>,std::allocator<_Ty>>::push_back(const std::shared_ptr<GameObject> &)': cannot convert argument 1 from 'std::shared_ptr<BulletModel>' to 'std::shared_ptr<GameObject> &&' 2> with 2> [ 2> _Ty=std::shared_ptr<GameObject> 2> ] 2> WorldModel.cpp(34): note: Reason: cannot convert from 'std::shared_ptr<BulletModel>' to 'std::shared_ptr<GameObject>' 2> WorldModel.cpp(34): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 

Why?

  • Give the full text of the error messages. - Vlad from Moscow
  • @VladfromMoscow updated the original message. - user1496491
  • Try simply writing GameObject * p = new BulletModel; What will the compiler say? In general, a minimal verifiable example is required that demonstrates the problem. - Vlad from Moscow
  • one
    Can a GameObject not be a public base class for BulletModel ? - αλεχολυτ
  • Check out what a minimal reproducible example is and try to implement it as a single source code file. Placing the shared_ptr derived class into a vector from the shared_ptr base should work . - αλεχολυτ

1 answer 1

The error turned out to be very ridiculous, but difficult to recognize by compiler errors. I followed the advice on using pre-declarations in header files instead of inclusions, and transferring the inclusions themselves to the implementation files to avoid cyclic inclusions.

To be honest, I do not know how this recommendation is relevant, but so far it looks like the only way to solve the problem with cyclic inclusions.

I executed the preliminary declaration, but forgot to include the header file in the implementation. Usually, in these cases, the compiler would display the error "Incomplete type", which immediately made it clear what the problem was, but the "impossibility to bring types" issued at this time was confusing.