Reputation: 415
This question gives answer only when the classes use each other as the member types, but not when they use the functions of each other. How to do it in the following example? Bar
is a singleton container which handles the operations done on all Bar
s.
// Foo.h
#include "Bar.h"
class Foo {
public:
Foo() { Bar::get_instance()->push_back(this); }
void do_something() {}
};
// Bar.h
#include "Foo.h"
#include <vector>
class Bar {
public:
Bar(const Bar &other) = delete;
void operator=(const Bar &) = delete;
static Bar *get_instance()
{
static Bar bar;
return &bar;
}
void push_back(Foo *foo) { foos_.push_back(foo); }
void do_something_all() { for (Foo *f : foos_) f->do_something(); }
private:
Bar() = default;
std::vector<Foo *> foos_;
};
Upvotes: 2
Views: 187
Reputation: 117851
You split it up. Define the classes but put the implementation part after the class definition.
class Foo {
public:
Foo(); // declare but do not implement
// this can be implemented here since it doesn't need Bar:
void do_something() { std::cout << "Foo::do_something()\n"; }
};
class Bar {
public:
Bar(const Bar&) = delete;
void operator=(const Bar&) = delete;
static Bar& get_instance() { // return a reference instead
static Bar bar;
return bar;
}
// you can store a pointer - but require a reference:
void push_back(Foo& foo) { foos_.push_back(&foo); }
// or else you need to check for nullptr in here:
void do_something_all() { for(Foo* f : foos_) f->do_something(); }
private:
Bar() = default;
std::vector<Foo*> foos_;
};
// Implementation part:
// Here Foo can use Bar
Foo::Foo() {
Bar::get_instance().push_back(*this);
}
Upvotes: 3
Reputation: 2364
Forward declaration will do the trick, forward decalre in .h and include the header in cpp.
// Bar.h
//#include "Foo.h"
#include <vector>
class Foo; // <---- this one
class Bar {
public:
Bar(const Bar &other) = delete;
void operator=(const Bar &) = delete;
static Bar *get_instance();
// move definition in cpp
void push_back(Foo *foo);
// move definition in cpp
void do_something_all();
private:
Bar() = default;
std::vector<Foo *> foos_;
};
// Bar.cpp
#include "Foo.h"
Bar* Bar::get_instance()
{
static Bar bar;
return &bar;
}
void Bar::push_back(Foo *foo)
{
foos_.push_back(foo);
}
void Bar::do_something_all()
{
for (Foo *f : foos_) f->do_something();
}
Upvotes: 1