0

The premise is: I'm making a particle system. I have a ParticleManager, which has a vector of ParticleSystem objects, which has a vector of type Particle. However, I also have the class Snowball, which inherits from Particle, and it has a ParticleSystem of it's own, as it leaves a trail of particles.

#pragma once
#include "ParticleSystem.h"

class Snowball : public Particle
{
private:
    ParticleSystem ps;
public:
    Snowball(){};
    Snowball(Point2D pos, RECT* viewport);
    void Update();
    void Draw(GraphicsM * pGraphicsModule);
};

This is the Snowball.h file, and the ParticleSystem one just has #include "Snowball.h" at the top, and uses Snowball throughout, as any given Particle can be a Snowball. How do I resolve this, either through a change of architecture or the order of code?

0

3 Answers 3

2

One option: instead of giving Snowball a member of type ParticleSystem, give it a pointer to ParticleSystem (preferably a shared_ptr or unique_ptr to preclude memory leaks). Then you don't need to #include ParticleSystem.h in Snowball.h; you just need to forward-declare it. Snowball's constructor would then need to move to the .cpp file and instantiate a new ParticleSystem there to store in the pointer.

Something like:

 // Snowball.h
 class ParticleSystem;

 class Snowball
 {
 private:
    std::shared_ptr<ParticleSystem> ps;

 public:
    Snowball();
    // rest the same
};

// Snowball.cpp

#include "Snowball.h"
#include "ParticleSystem.h"

SnowBall::SnowBall()
   : ps(std::make_shared<ParticleSystem>())
{
}

// rest the same except for ps. becoming ps->
Sign up to request clarification or add additional context in comments.

9 Comments

Do you mind giving some code to demonstrate how I'd do this? I just get ParticleSystem is undefined.
You could also use something like pimpl to get the ParticleSystem out of Snowball's header entirely, but that would be a more radical change.
The "class ParticleSystem;". Is that supposed to be the entire .h file?
"class ParticleSystem;" goes at the top of SnowBall.h in place of "#include ParticleSystem.h" The rest should be the same as what you had before, aside from changing ps to a pointer.
I'm still getting incomplete type errors with that in place when I try to create a new ParticleSystem inside Snowball
|
0

In cases when you need several classes that use each other as complete type, you can use something like this:

class TestClass1;
class TestClass2;


class TestClass1
{
    int val;
    TestClass2 foo();
};
class TestClass2
{
    int val;
    TestClass1 foo();
};


TestClass2 TestClass1::foo()
{
    /* ... */
}
TestClass1 TestClass2::foo()
{
    /* ... */
}

Comments

0

The other answers provide a good demonstration of how to work round the issue. However, have you considered restructuring your code so this isn't necessary? Normally, circular dependencies will cause other issues later.

An alternative structure is you could use composition instead of inheritance.

The circular dependency comes from the particle system using particles, but the particle also using the particle system. This is because snow ball is a particle.

Instead, you could have your snowball contain an instance of a particle and an instance of the particle system. This is called composition as you are composing your snowball out of a particle and a particle system.

This way Particle depends on Particle System and snowball depends on both and hence no circular dependency.

2 Comments

But I'm using Snowball as a Particle, and not doing so would involve a lot of duplicate code
You are in the best position to judge this. I provided this answer an an alternative perspective as sometimes one can't see the wood for the trees!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.