I am creating an object using static member function of a class. and then calling a function inside.
int main(){
int a = 49;
auto foo = Foo::createFoo(a);
foo->study();
}
Implementation
for this example lets have study()
display a value.
Structure wise I do have constraints to have the below interface and then the static method returning the object
class I_Foo{
public:
virtual void study(void) = 0;
};
class Foo : public I_Foo{
public:
static Foo* createFoo(int x_) {
return new Foo(x_);
}
void study() override{
std::cout << "studied: "<< st << std::endl;
}
protected:
Foo(int a) : st(a) {}
int st = 0;
};
This above implementation is absolutely working good and as expected i.e., variable a
should be displayed as studied: a
Now I want to change the behaviour of this
Lets say for values below 50, the above implementation should remain "unchanged" i.e., variable a
should be displayed as studied: a
However as the value becomes 50 and above then the output should display studied: a 100
#include <iostream>
class I_Foo{
public:
virtual void study(void) = 0;
};
template<int>
class FooImpl;
class Foo : public I_Foo {
public:
static Foo* createFoo(int x_) {
Foo* foo = nullptr;
if (x_>=50) {
foo = new FooImpl<2>(x_);
}
else {
foo = new FooImpl<1>(x_);
}
return foo;
}
};
template<int FT = 1>
class FooImpl : public Foo{
public:
void study() override{
std::cout << "studied: "<< st << std::endl;
}
FooImpl(int a) : st(a) {}
int st = 0;
};
template<>
void FooImpl<2>::study() override{
std::cout << "studied: "<< st 100 << std::endl;
}
int main()
{
int a = 56;
auto foo = Foo::createFoo(a);
foo->study();
}
This obviously doesnot compile as the Foo
has no clue what FooImpl
is!
Please suggest how can I make this work. The requirement is to keep the main function untouched but have the new functionality.
Please note Yes, I know this could be solved by if statement, but that is not the point. It has a complex implementation in reality I just tried to present it in a fairly understandable problem to study how these templates could work.
EDIT 1
After first editt I seeing the below compliation error
CodePudding user response:
As I wrote in the comment: Do not implement createFoo
function inside the class declaration.
#include <iostream>
class I_Foo {
public:
virtual void study(void) = 0;
};
class Foo : public I_Foo {
public:
// here just DECLARE the method...
static Foo *createFoo(int x_);
};
/********/
/* SNIP */
/********/
// ...and IMPLEMENT it there
Foo *Foo::createFoo(int x_) {
if (x_>=50) {
return new FooImpl<2>(x_);
} else {
return new FooImpl<1>(x_);
}
}
int main() {
int a = 56;
auto foo = Foo::createFoo(a);
foo->study();
}