Reputation: 529
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.
Upvotes: 1
Views: 97
Reputation: 1
"... 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.
Upvotes: 1
Reputation: 5866
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;
}
Upvotes: 0
Reputation: 7881
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.
Upvotes: 0