How can someone implement this pattern:
class Base {//doesn't know anything about potential descendant-classes, like Child
public:
Base * foo( void) {
//some code
return ( Base *) new !Child-constructor!();
}
};
class Child : public Base { };
//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>
using namespace std;
int main( void) {
Base * base_p = Child().f();
cout << typeid( *base_p).name(); //expected to get "Child"
return 0;
}
I can't find the right syntax for this type of constructions (calling the "potential" child constructor).
UPD: I forgot to mention (didn't think that there can be missunderstanding), that Child
class must not be known in definition of Base
. So I wanted foo
to call the constructor of the class in which it's gonna be inherited.
"... that Child class must not be known in definition of Base. So I wanted foo to call the constructor of the class in which it's gonna be inherited."
IMHO the easiest way is to provide a templated factory function with Base
class Base {
public:
template<class Derived>
static std::unique_ptr<Base> foo( void) {
//some code
return std::unique_ptr<Base>(new Derived());
}
};
class Child : public Base {
public:
Child() {}
virtual ~Child() {}
};
int main() {
std::unique_ptr<Base> p = Base::foo<Child>();
return 0;
}
Check the compilable sample here please.
This design is awful, btw.
//terriblecode.hpp
struct Base
{
Base * foo(void);
};
struct Child : public Base{};
//terriblecode.cpp
Base* Base::foo() {return (Base*) new Child();}
The definition of child isn't needed untill the definition of foo. Separate your declaration from your definition of member functions, and it is pretty easy to do.
Just need to make sure you let the compiler know about your derived class before the first use:
class Child; // forward declaration
class Base {
public:
Base * foo( void);
};
class Child : public Base { };
// the function needs to be defined after the "Child" is known
Base * Base::foo( void) {
//some code
return new Child; // will be automatically type-cast to base class
}
//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>
using namespace std;
int main( void) {
Base * base_p = Child().f();
cout << typeid( *base_p).name(); //expected to get "Child"
return 0;
}
However, I'd recommend a different pattern:
class Child; // forward declaration
class Base {
public:
static Base * foo( void); // static "factory" method
};
class Child : public Base { };
// the function needs to be defined after the "Child" is known
Base * Base::foo( void) {
//some code
return new Child; // will be automatically type-cast to base class
}
//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>
using namespace std;
int main( void) {
Base * base_p = Base::f(); // use scope resolution, not object's method
cout << typeid( *base_p).name(); //expected to get "Child"
return 0;
}