是否可以在派生类中使用模板方法重写虚拟方法?



我想用派生类中的模板方法覆盖基类中的虚拟方法;只是想知道是否有任何聪明的方法或解决方法来实现这一目标。

#include <iostream>
using namespace std;
struct A
{
virtual void AF(int i)
{
std::cout << "Function in A" << std::endl;
}
virtual void af(int i)
{
std::cout << "Function in A" << std::endl;
}
};
struct B
{
virtual void BF(int i)
{
std::cout << "Function in B" << std::endl;
}
virtual void bf(int i)
{
std::cout << "Function in B" << std::endl;
}
};
template<bool IS_A>
struct C : public A, public B
{
template<class I>
typename std::enable_if<std::is_same<int, I>::value && IS_A,void>::type AF(I i)
{
std::cout << "Function override from A in C" << std::endl;
}
template<class I>
typename std::enable_if<std::is_same<int, I>::value && !IS_A,void>::type BF(I i)
{
std::cout << "Function override from B in C" << std::endl;
}
template<class I>
void af(I i)
{
std::cout << "Function override from A in C" << std::endl;
}
template<class I>
void bf(I i)
{
std::cout << "Function override from B in C" << std::endl;
}
};

int main() {
int i(0);
{
A * a = new C<true>();
a->AF(i);
a->af(i);
}
{
B * b = new C<false>();
b->BF(i);
b->bf(i);
}
return 0;
}

输出为:

A 中的函数/
  • /希望这是 C 中 A 的函数覆盖
  • A 中的函数/
  • /希望这是 C 中 A 的函数覆盖
  • B 中的函数/
  • /希望这是 C 中 B 的函数覆盖
  • B 中的函数/
  • /希望这是 C 中 B 的函数覆盖

谢谢。

首先,要根据IS_A"启用/禁用"成员函数,您可以定义 C 的truefalse特化:

template <bool IS_A>
struct C;
template <>
struct C<true> : A, B
{
// functions only defined for IS_A == true
};
template <>
struct C<false> : A, B
{
// functions only defined for IS_A == false
}

要引入模板的覆盖,您可以覆盖 A 和 B 中的那些,您在其中调用模板:

void af(int i) override { af<int>(i); }
void bf(int i) override { bf<int>(i); }

您可以使用 CRTP 习惯用法来执行此操作:

#include <iostream>
#include<type_traits>
struct A
{
virtual void AF(int)
{
std::cout << "Function in A" << std::endl;
}
virtual void af(int)
{
std::cout << "Function in A" << std::endl;
}
};
struct B
{
virtual void BF(int)
{
std::cout << "Function in B" << std::endl;
}
virtual void bf(int)
{
std::cout << "Function in B" << std::endl;
}
};
template<typename D>
struct CRTP: public A, public B
{
template<typename I> void CAF(I i) { A::AF(i); }
template<typename I> void af(I i) { A::af(i); }
template<typename I> void CBF(I i) { B::BF(i); }
template<typename I> void cbf(I i) { B::bf(i); }
void AF(int i) override { static_cast<D*>(this)->CAF(i); }
void af(int i) override { static_cast<D*>(this)->caf(i); }
void BF(int i) override { static_cast<D*>(this)->CBF(i); }
void bf(int i) override { static_cast<D*>(this)->cbf(i); }
};
template<bool IS_A>
struct C : CRTP<C<IS_A>>
{
template<class I>
void CAF(I i)
{
std::cout << "Function override from A in C" << std::endl;
}
template<class I>
void CBF(I i)
{
std::cout << "Function override from B in C" << std::endl;
}
template<class I>
void caf(I i)
{
std::cout << "Function override from A in C" << std::endl;
}
template<class I>
void cbf(I i)
{
std::cout << "Function override from B in C" << std::endl;
}
};
int main()
{
int i(0);
{
A * a = new C<true>();
a->AF(i);
a->af(i);
}
{
B * b = new C<false>();
b->BF(i);
b->bf(i);
}
return 0;
}

最新更新