Circular dependency with double dispatch - c++

I'm trying to implement the double dispatch pattern but I get a circular dependency that I can't resolve with forward declaration (as it was resolved in this problem link).
Below is an example of my problem:
header 1:
class Object
{
virtual void dispatchAdd(Collection& c) const = 0;
};
class Blockage: Object
{
virtual void dispatchAdd(Collection& c) const
{
c.add(*this);
}
};
class Boundary: Object
{
virtual void dispatchAdd(Collection& c) const
{
c.add(*this);
}
};
header 2:
class Collection
{
public:
void add(const Blockage& b)
{ ... }
void add(const Boundary& b)
{ ... }
...
private:
boost::unordered_set<Boundary> m_boundaries;
boost::unordered_set<Blockage> m_blockages;
}
I can't forward declare Boundary and Blockage in header 2, because I need a complete type to use boost::unordered_set. Any advice to resolve this problem?

Forward declare Collection in header 1 and move the implementations for dispatchAdd out of the header file and into the source file.
objects.h (i.e. "header 1"):
class Collection;
class Object
{
virtual void dispatchAdd(Collection& c) const = 0;
};
class Blockage: Object
{
virtual void dispatchAdd(Collection& c) const;
};
class Boundary: Object
{
virtual void dispatchAdd(Collection& c) const;
};
objects.cpp
#include "objects.h" // i.e. "header 1"
#include "collection.h" // i.e. "header 2"
void Blockage::dispatchAdd(Collection& c) const
{
c.add(*this);
}
void Boundary::dispatchAdd(Collection& c) const
{
c.add(*this);
}

Related

using header files with functors in c++

I am attempting to use functors in a larger-scope project. I managed to implement a functor when it was on its own, but I am having a lot of trouble figuring out where I define things in the header file (.h) vs the .ccp file so that I can access my functor in the rest of my program. When the functor is all together it appears as such:
class SpecialAttack {
public:
SpecialAttack() {};
virtual bool operator() (double timer) = 0;
};
class BallAttack : public SpecialAttack {
public:
BallAttack() {};
virtual bool operator() (double timer) { return (timer==0); }
};
class SpiderAttack : public SpecialAttack {
public:
SpiderAttack() {};
virtual bool operator() (double timer) { return true; }
};
double special_attack(double timer, SpecialAttack* func) {
return (*func)(timer);
}
I cannot figure out how to break this up into the appropriate files so that I can then reference it in the rest of my code. What parts should i put in the .h file and what parts go in the .ccp file? Thanks!
Splitting functors between .hpp and .cpp files follows the same pattern of declaration and definition used for any class with member functions.
attack.hpp
#pragma once
class SpecialAttack {
public:
SpecialAttack();
virtual bool operator() (double timer) = 0;
};
class BallAttack : public SpecialAttack {
public:
BallAttack();
virtual bool operator() (double timer) override;
};
class SpiderAttack : public SpecialAttack {
public:
SpiderAttack();
virtual bool operator() (double timer) override;
};
attack.cpp
#include "attack.hpp"
SpecialAttack::SpecialAttack() {
}
BallAttack::BallAttack() {
}
/*virtual*/ bool BallAttack::operator() (double timer) /*override*/ {
return (timer==0);
}
SpiderAttack::SpiderAttack() {
}
/*virtual*/ bool SpiderAttack::operator() (double timer) /*override*/ {
return true;
}

How do you implement "delegation" for classes efficiently in C++?

In Objective C the language has built in support for delegation of classes to other classes. C++ does not have such feature (one class as a delegate of another class) as part of the language. A way to mimic that is to separate declaration and implementation this way:
In header file a.h:
class AImpl;
class A
{
public:
A();
void f1();
int f2(int a, int b);
// A's other methods...
private:
AImpl *mImpl;
};
In the .cpp (implementation file):
#include "a.h"
class AImpl
{
public:
AImpl();
// repeating the same method declarations from A
void f1();
int f2(int a, int b);
// AImpl's other methods
};
AImpl::AImpl()
{
}
void AImpl:f1()
{
// actual implemetation
}
int AImpl::f2(int a, int b)
{
// actual implmentation
}
// AImpl's other methods implementation
A::A()
{
mImpl = new AImpl();
}
// A's "forwarder"
void A::f1()
{
mImpl->f1();
}
int A::f2(int a, int b)
{
return mImpl->f2(a, b);
}
// etc.
This requires manually creating all "forwarder" functions in the class that would delegate to another class to do the actual work. Tedious, to say the least.
The question is: is there a better or more productive way to achieve this effect using templates or other C++ langage constructs?
Yes it's possible. One of possible examples is:
struct WidgetDelegate
{
virtual ~WidgetDelegate() {}
virtual void onNameChange(std::string newname, std::string oldname) {}
};
class Widget
{
public:
std::shared_ptr<WidgetDelegate> delegate;
explicit Widget(std::string name) : m_name(name){}
void setName(std::string name) {
if (delegate) delegate->onNameChange(name, m_name);
m_name = name;
}
private:
std::string m_name;
};
Usage:
class MyWidgetDelegate : public WidgetDelegate
{
public:
virtual void onNameChange(std::string newname, std::string oldname) {
std::cout << "Widget old name: " << oldname << " and new name: " << newname << std::endl;
}
};
int main()
{
Widget my_widget("Button");
my_widget.delegate = std::make_shared<MyWidgetDelegate>();
my_widget.setName("DoSomeThing");
return 0;
}
Required includes are:
#include <string>
#include <iostream>
#include <memory>
You can implement a virtual interface in the base class.
However, if you really want to delegate, then you can overload the operator-> to delegate all calls.
You won't need anymore the forwarding methods:
#include <iostream>
#include <string>
using namespace std;
class AImpl;
class A
{
public:
A();
//Overloading operator -> delegates the calls to AImpl class
AImpl* operator->() const { return mImpl; }
private:
AImpl *mImpl;
};
class AImpl
{
public:
void f1() { std::cout << "Called f1()\n"; }
void f2() { std::cout << "Called f2()\n"; }
};
A::A()
{
mImpl = new AImpl();
}
int main()
{
A a;
a->f1(); //use a as if its a pointer, and call functions of A
A* a1 = new A();
(*a1)->f2();
}

C++ class definition split into two headers?

Is it possible in C++ to split the definition of class members in two headers? What would be the appropriate way to code it?
For instance:
a1.h
class A {
public:
int var;
void foo1(int b);
}
a1.cpp
#include "a1.h"
void A::foo1(int b) {
cout << b;
}
a2.h
[extend] class A {
public:
void foo2(double c);
}
a2.cpp
#include "a2.h"
void A::foo2(double c) {
cout << c;
}
You can't extend a class that way, but you can use the pimpl pattern:
class A {
public:
void foo1(int b);
private:
AImpl* pimpl;
}
and then have AImpl.h and AImpl.cpp that hides all the private details.

Error Msg: Pure Abstract Class wrapped in a Namespace in C++

Need help with implementing a pure abstract class via inheritance, using namespace to wrap all my classes to avoid conflict with others.
I have been able to build and run the code successfully if I remove namespace wrapper from my abstract class and all classes that inherit from my pure abstract class.
It seems like Visual Studio 2010 compiler is complaining that despite all classes are in the same namespace, the abstract class's pure abstract method is not implemented.
Any help would be much appreciated.
//IBaseClass.h
//forward declaration
class ConcreteClass;
//namespace MyCustomNamespace
//{
class IBaseClass
{
public:
virtual ~IBaseClass() { /*virtual destructor*/ }
//Behaviours...
virtual bool Method001( const ConcreteClass &cc ) = 0;
//virtual bool Method002(/*some input*/) = 0;
};
//} /*NAMESPACE*/
//-----------------------------------------
//ParentClass.h
//namespace MyCustomNamespace
//{
class ParentClass : virtual public IBaseClass
{
private:
int a;
public:
virtual ~ParentClass() { /*virtual destructor*/ }
//getter-setter implemented in ParentClass.cpp file...
void setA(const int aa);
const int getA() const;
};
//} /*NAMESPACE*/
//-----------------------------------------
//ConcreteClass.h
//namespace MyCustomNamespace
//{
class ConcreteClass: public ParentClass
{
private:
int b;
public:
virtual ~ConcreteClass() { /*virtual destructor*/ }
//getter-setter...
void setB(const int bb);
const int getB() const;
bool Method001( const ConcreteClass &cc ); //re-declaring IBase abstract method...
};
//} /*NAMESPACE*/
//-----------------------------------------
//ConcreteClass.cpp
//namespace MyCustomNamespace
//{
void ConcreteClass::setB(const int bb) { this->b = bb; }
const int ConcreteClass::getB() const { return this->b; }
bool ConcreteClass::Method001( const ConcreteClass &cc )
{
//implementation code goes here...
return false;
}
//} /*NAMESPACE*/
The problem is that your forward class has been declared in another namespace (specifically, the global namespace). Thus, the virtual to override is a different symbol with a different parameter type.
As written, the compiler matches ConcreteClass to the forward declaration it sees in the global namespace when declared in the base:
virtual bool Method001( const ConcreteClass &cc ) = 0;
When you declare Method001 in ConcreteClass:
virtual bool Method001( const ConcreteClass &cc );
the compiler matches cc to MyCustomNamespace::ConcreteClass because that is a more accurate match.
To resolve the issue, just place your forward declaration in the proper namespace:
namespace MyCustomNamespace {
class ConcreteClass;
}

2 classes trying to access each others methods, can't solve dependancies

I am learning c++ and writing a game. it was going more or less okey. but the bigger it gets the more trouble i get from dependencies.
How can i fix this kind of dependency?
class myClass_2;
class myClass_1 {
private:
myClass_2 * myclass2;
public:
myClass_1() {}
void setUp(myClass_2 &myclass) {
myclass2 = &myclass;
}
void doSomething_1(){
myclass2->doSomething_2();
}
};
class myClass_2 {
private:
myClass_1 * myclass1;
public:
myClass_2() {}
void setUp(myClass_1 &myclass) {
myclass1 = &myclass;
}
void doSomething_2() {
myclass1->doSomething_1();
}
};
int main () {
myClass_1 class_1;
myClass_2 class_2;
class_1.setUp(class_2);
class_2.setUp(class_1);
return 1;
}
You need to separate the class definition in a header file (with .h extension) and a source file (.cpp or .cc file). And then use #include to include the header file to solve these types of problems. See this link for a more detailed explanation: Header files in C++
You need to define your classes in header files, and define member functions in cpp files.
//class1.h
class myClass_2;
class myClass_1 {
private:
myClass_2 * myclass2;
public:
myClass_1();
void setUp(myClass_2 &myclass);
void doSomething_1();
};
//class1.cpp
#include "class1.h"
#include "class2.h"
myClass_1::myClass_1() {
}
void myClass_1::setUp(myClass_2 &myclass) {
myclass2 = &myclass;
}
void myClass_1::doSomething_1() {
myclass2->doSomething_2();
}
Then do the same for myClass_2. You don't need myClass_2's member function definition in order to call the member functions, you only need the class definition found in class2.h
Move the function bodies outside the class bodies.
class myClass_2;
class myClass_1 {
private:
myClass_2 * myclass2;
public:
myClass_1() {}
void setUp(myClass_2 &myclass);
void doSomething_1();
};
class myClass_2 {
private:
myClass_1 * myclass1;
public:
myClass_2() {}
void setUp(myClass_1 &myclass);
void doSomething_2();
};
void myClass_1::setUp(myClass_2 &myclass) {
myclass2 = &myclass;
}
void myClass_1::doSomething_1(){
myclass2->doSomething_2();
}
void myClass_2::setUp(myClass_1 &myclass) {
myclass1 = &myclass;
}
void myClass_2::doSomething_2() {
myclass1->doSomething_1();
}
int main () {
myClass_1 class_1;
myClass_2 class_2;
class_1.setUp(class_2);
class_2.setUp(class_1);
return 1;
}
In professional object-oriented programming class function declarations and definitions are often kept in separate *.h and *.cpp files. Then the *.h file is included in the main file.
I wish you had said what trouble you were getting exactly.
If the trouble is that it can't compile myClass_1::doSomething1() because it doesn't know how to call myclass2->doSomething2(), the solution is to move the definition of myClass_1::doSomething1() below the definition of myclass_2:
class MyClass_1 {
...
void doSomething_1(); // just declare it here
...
}
class My_Class_2 {
...
void doSomething_2();
...
}
void MyClass_1::doSomething_1() // now define it
{
myclass2->doSomething_2();
}