I'm trying to call a parent constructor, with a given pointer to sibling object:
class Base{
public:
Base(const Base&) =default;
};
#include "daughter.h" // <-- problem! I'll come to this in a second.
class Son: public Base{
public:
Son(Daughter* d) : Base(*d){};
};
But (and here comes the problem), this relationship goes in both directions:
// daughter.h
class Son; // forward declare needed
class Daughter: public Base{
public:
Daughter(Son* s) : Base(*d){};
};
Uh-oh: (link to run)
error: no matching function for call to 'Daughter::Daughter(Base&)'
note: candidates are:
note: Daughter::Daughter(const Base&)
note: no known conversion for argument 1 from 'Daughter' to 'const Base&'
So, the issue arises since at that point - where Son
is an incomplete type - it is not known that it inherits from Base
, and so this constructor doesn't match.
I have been able to 'solve' it:
Daughter::Daughter(Son* s) : Base( *reinterpret_cast<Base>(*s) ){};
But this seems bad practice - I don't think I should need to reinterpret_cast
for something of such innocent intent - we all know Son
will be a derived class of Base
!
Is there a better way of dealing with this?
NB: While possibly true that it comes from bad overall design - "[I] shouldn't need to construct a parent from a sibling." - please bear in mind that I have reduced this to a very minimal example from a much larger design (with many more siblings, and many more constructors for each) in which doing this is necessary in a couple of places.
You have to define the constructors in cpp files to break the circular dependency:
// base.h
class Base {
public:
Base(const Base& b) { ... }
};
// son.h
#include "base.h" // include because you need the definition for inheritance
class Daughter; // don't include, just forward declare
class Son: public Base {
public:
Son(Daughter* d);
};
// son.cpp
#include "son.h"
#include "daughter.h"
Son::Son(Daughter* d) : Base(*d) {}
// daughter.h
#include "base.h" // include because you need the definition for inheritance
class Son; // forward declare needed
class Daughter: public Base {
public:
Daughter(Son* s);
};
// daughter.cpp
#include "daughter.h"
#include "son.h"
Daughter::Daughter(Son* s) : Base(*s) {}