Two classes relying on each other

Started by
8 comments, last by ingframin 7 years, 6 months ago
So here's the two classes I'm having trouble with (they are in seperate header files)
aggressiveEntity:
https://github.com/Nyapp/Cell/blob/master/src/classes/aggressive.h
Bullet:
https://github.com/Nyapp/Cell/blob/master/src/classes/bullet.h
as you can see, aggressiveEntities have an array of Bullets and Bullets have a pointer to their owner entity.

In file included from src/classes/aggressive.h:27:0,
from src/classes/player.h:25,
from src/engine.h:33,
from src/main.cpp:24:
src/classes/bullet.h: At global scope:
src/classes/bullet.h:37:3: error: ‘aggressiveEntity’ does not name a type
aggressiveEntity* owner;
^~~~~~~~~~~~~~~~
src/classes/bullet.h: In member function ‘void Bullet::update()’:
src/classes/bullet.h:55:31: error: ‘owner’ was not declared in this scope
if (collisionDetect()) { owner->destroyBullet(id); }
^~~~~
src/classes/bullet.h:63:31: error: ‘owner’ was not declared in this scope
if (collisionDetect()) { owner->destroyBullet(id); }
^~~~~
src/classes/bullet.h:75:31: error: ‘owner’ was not declared in this scope
if (collisionDetect()) { owner->destroyBullet(id); }
^~~~~
src/classes/bullet.h:83:31: error: ‘owner’ was not declared in this scope
if (collisionDetect()) { owner->destroyBullet(id); }
^~~~~

Advertisement
And the compiler doesn't like it.

It would be helpful if you included the compiler error message.

EDIT: That said, in AGGRESSIVE_CLASS you have "class Bullet" randomly near the top, which at the very least would need a semi-colon if you're wanting to forward-declare it.

EDIT 2: Line #32 in aggressive.h.

Hello to all my stalkers.

 

And the compiler doesn't like it.

 
It would be helpful if you included the compiler error message.
EDIT: That said, in AGGRESSIVE_CLASS you have "class Bullet" randomly near the top, which at the very least would need a semi-colon if you're wanting to forward-declare it.
 
ok I fixed that random "class Bullet" and I also had to link to the source code because every time I edit the post everything between the code tags goes on one line
You can add a forward declaration instead of including the header.

In bullet.h replace
#include "agressive.h"
With
class aggressiveEntity;
That simply tells the compiler a class with the name aggressiveEntity exists. You still have to ensure that agressive.h is included. wherever bullet.h is included.

EDIT: Looking at it further, you would be better off just removing that circular dependency altogether. When you create the bullet, just copy over any needed information from aggressiveEntity onto the new bullet instance when you create it.
My current game project Platform RPG

EDIT: Looking at it further, you would be better off just removing that circular dependency altogether. When you create the bullet, just copy over any needed information from aggressiveEntity onto the new bullet instance when you create it.


I need the address of the owner so that the owner can delete the bullet from memory - unless there's some other way I could do it? Also, how do you forward declare a member function? (Bullet uses aggressiveEntity::destroyBullet(int))

I need the address of the owner so that the owner can delete the bullet from memory - unless there's some other way I could do it? Also, how do you forward declare a member function? (Bullet uses aggressiveEntity::destroyBullet(int))


You could have a boolean on the bullet if it is active or not and have the agressiveEntity check every update for any inactive bullets and delete them.
My current game project Platform RPG

Split things into .h and .cpp files.

Forward-declare classes in the .h where you can, and #include where you have to.

There is no reason for bullet.h having to know the implementation details of aggressive just to have a pointer to the owner.

In bullet.h, just forward-declare aggressive. Also declare the functions for bullet, but don't define them.

In bullet.cpp, include aggressive.h, and do the function implementations there.

Hello to all my stalkers.

I need the address of the owner so that the owner can delete the bullet from memory - unless there's some other way I could do it?


The shooter does not need to own the bullets once they're fired. You can have an external container that holds bullets and deals with their logic independently.


class ScaryMonster {
public:

private:
  void immaShootDisFoo(SimpleScene& myParentScene) {
    myParentScene.spawnBullet(allKindsOfArgs);
  }

};

class SimpleScene {
public:
  void spawnBullet(location, direction, speed, etc) {
    bullets.emplace_back(bullet constructor arguments);
  }

  void updateBullets() {
    for(auto& bullet : bullets) { bullet.update(); }
    bullets.erase(std::remove_if(bullet.begin(), bullet.end(), [](Bullet& b) { return b.isDead; }) bullet.end());
  }

  //...

private:
  ScaryMonster blerg;
  std::vector<Bullet> bullets;
  ShinyHero derp;

};
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

EDIT: Looking at it further, you would be better off just removing that circular dependency altogether. When you create the bullet, just copy over any needed information from aggressiveEntity onto the new bullet instance when you create it.


I need the address of the owner so that the owner can delete the bullet from memory - unless there's some other way I could do it? Also, how do you forward declare a member function? (Bullet uses aggressiveEntity::destroyBullet(int))

Do you want it so that if the owner of the bullet dies, the bullets they own goes away? That's usually not the norm, but maybe that's what you want?

Remove the circular dependency and think better about your logic. An entity class cannot be responsible for managing memory, especially allocation and deal location of other kind of objects.
Use an external object to "link" entity and bullet and that class can be the factory for bullets.
You can also use a function for that and keep the bullets in a standard container.
In your implementation you have also a good probability of killing the entity before the bullets by mistake and having memory leaks or segfaults if the bullet tries to access the in wild pointer of the "dead" entity.

This topic is closed to new replies.

Advertisement