, , :
1) . .
class FooWrapper : public Wrapper< double, Foo, &Foo::set >, public Foo
{
public:
FooWrapper() : Wrapper(this){}
};
:
FooWrapper fooWrapper;
fooWrapper.do_something(1.0);
std::cout << fooWrapper.get() << std::endl;
, , .
2) :
template<typename argType1, class classType1>
class FooWrapper2 : public Wrapper<argType1, classType1, &classType1::set>, public classType1
{
public:
FooWrapper2()
: classType1(),
Wrapper<argType1, classType1, &classType1::set>(this)
{
}
};
, , :
FooWrapper2<double, Foo> fooWrapper2;
fooWrapper2.do_something(1.0);
std::cout << fooWrapper2.get() << std::endl;
3) , :
template<typename argType1>
class FooWrapper3 : public FooWrapper2<argType1, Foo>
{
public:
FooWrapper3()
{
}
};
, , ( , ):
FooWrapper3<double> fooWrapper3;
fooWrapper3.do_something(1.0);
std::cout << fooWrapper3.get() << std::endl;
4) This parameter breaks the base wrapper class and uses the interface. Just pass in the interfaces just like the wrappers, and you can do most of the work.
template <typename ArgType>
class Do_something {
public:
virtual void do_something(ArgType value) = 0;
};
template<typename ArgType>
class FooWrapper4 : public Foo, public Do_something<ArgType>
{
public:
virtual void do_something(ArgType value)
{
set(1.0);
}
};
Testing program I played:
class Foo {
public:
Foo() : f_(0.0) {}
void set(double v) { f_ = v * 2.1; }
double get() { return f_; }
private:
double f_;
};
template <typename ArgType, typename ClassType, void (ClassType::*Method)(ArgType)>
class Wrapper {
public:
explicit Wrapper(ClassType *cls) : cls_(cls) {}
void do_something(ArgType value) {
(cls_->*Method)(value);
}
private:
ClassType *cls_;
};
class FooWrapper : public Wrapper< double, Foo, &Foo::set >, public Foo
{
public:
FooWrapper() : Wrapper(this){}
};
template<typename argType1, class classType1>
class FooWrapper2 : public Wrapper<argType1, classType1, &classType1::set>, public classType1
{
public:
FooWrapper2()
: classType1(),
Wrapper<argType1, classType1, &classType1::set>(this)
{
}
};
template<typename argType1>
class FooWrapper3 : public FooWrapper2<argType1, Foo>
{
public:
FooWrapper3()
{
}
};
template <typename ArgType>
class Do_something {
public:
virtual void do_something(ArgType value) = 0;
};
template<typename ArgType>
class FooWrapper4 : public Foo, public Do_something<ArgType>
{
public:
virtual void do_something(ArgType value)
{
set(1.0);
}
};
int main(int argc, char ** argv) {
Foo foo;
Wrapper<double, Foo, &Foo::set> wrapper(&foo);
wrapper.do_something(1.0);
std::cout << foo.get() << std::endl;
FooWrapper fooWrapper;
fooWrapper.do_something(1.0);
std::cout << fooWrapper.get() << std::endl;
// outputs "2.1"
FooWrapper2<double, Foo> fooWrapper2;
fooWrapper2.do_something(1.0);
std::cout << fooWrapper2.get() << std::endl;
FooWrapper3<double> fooWrapper3;
fooWrapper3.do_something(1.0);
std::cout << fooWrapper3.get() << std::endl;
FooWrapper4<double> fooWrapper4;
fooWrapper4.do_something(1.0);
std::cout << fooWrapper4.get() << std::endl;
return 0;
}