Является ли шаблон C ++ способным «пересылать любую функцию класса»? из родительского класса?

class Foo {
public:
void methodA();
};

class ManagedFoo {
Foo fooInst;
public:
void methodA() { doSomething(); fooInst.methodA();}
};

Теперь я хочу сделать ManagedFoo шаблоном, управляющим любым классом, не только Foo, и прежде чем вызывать любую функцию Foo, сначала вызовите doSomething.

template<typename _TyManaged>
class Manager {
_TyManaged _managedInst;
void doSomething();
public:
/*Forward every function called by _managedInst*/
/*How to write this?*/
};

Я хочу сделать его таким же, сделать его заменяемым между этими двумя классами, вот так:

Foo* foo = new Foo();
foo->methodA();

Manager<Foo> managedFoo = new Manager<Foo>();
managedFoo->methodA(); //Hope it call Manager::doSomething() first then call _managedInst.methodA();

Может ли шаблон C ++ 11 сделать такую ​​вещь? если ответ да, то как?

4

Решение

Решение на основе оператора-> перегрузки:

#include <iostream>
#include <memory>

class A {
public:
void foo() { std::cout << "foo\n"; }
void bar() { std::cout << "bar\n"; }
};

template <typename T>
class ManagedBase {
std::shared_ptr<T> _inst;
public:
ManagedBase(const std::shared_ptr<T> inst) : _inst(inst) { }
virtual ~ManagedBase() { }

std::shared_ptr<T> operator->() {
before();
return this->_inst;
}

virtual void before() =0;
};template <typename T>
class ManagedPrint : public ManagedBase<T> {
public:
ManagedPrint(const std::shared_ptr<T> inst) : ManagedBase(inst) { }

virtual void before() {
std::cout << "Said: ";
}
};int main() {
auto ma = ManagedPrint<A>(std::make_shared<A>());
ma->bar();      // Said: foo
ma->bar();      // Said: bar
}
6

Другие решения

Что-то вроде этого?

template<typename _TyManaged>
class Manager {
_TyManaged _managedInst;
void doSomething();
public:
_TyManaged* operator->() {
doSomething();
return &_managedInst;
}
};
3

Это может решить вашу проблему. Но я все еще не уверен, что вы хотите сделать с вашим классом менеджера.

class Foo {
public:
void methodA();
};

template<typename T>
class ManagedFoo : public T {
public:
// some further extensions
};

И, конечно, таким образом вы меняете семантику класса Foo менеджером из:
Оно имеет
в
Это
Так что я не уверен, правда ли это в вашем случае.

2
По вопросам рекламы [email protected]