寻找c++成员函数覆盖(非虚拟)的解决方案
looking for solution of c++ member function override (non virtual)
我有两个类:
struct A {
template <typename T>
void print(T& t){
// do sth specific for A
}
};
struct B : A {
template <typename T>
void print(T& t){
// do sth specific for B
}
};
在这种情况下,不能编译带有虚函数的更通用的基类(A和B都继承了虚函数),因为没有虚的for模板。由于我试图将所有A或B对象委托给同一个"接口",有人有办法解决这个问题吗?提前谢谢你。
真诚,小君
您可以考虑使用使用CRTP。
template<typename Derived>
struct Base {
template <typename T>
void print(T& t){
static_cast<Derived*>(this)->print(t);
}
};
struct A : Base<A> {
// template print
};
struct B : Base<B> {
// template print
};
使用例子:
template<typename T, typename ARG>
void foo (Base<T>* p, ARG &a)
{
p->print(a);
}
这个方法将被调用为
foo(pA, i); // pA is A*, i is int
foo(pB, d); // pB is B*, d is double
使用代理类获取B的方法
class A {
public:
friend class CProxyB;
virtual CProxyB* GetCProxyB() = 0;
};
class B;
class CProxyB
{
public:
CProxyB(B* b){mb = b;}
template <typename T>
void printB(T& t)
{
mb->print(t);
}
B* mb;
};
class B:public A {
public:
virtual CProxyB* GetCProxyB(){return new CProxyB(this);};
template <typename T>
void print(T& t){
printf("OK!!!!!n");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* a = new B;
CProxyB* pb = a->GetCProxyB();
int t = 0;
pb->printB(t);
return 0;
}
两个选项:
选项一:虚拟化方法,如果用户不提供实现,则使用基类。
template <typename T>
struct A {
virtual void print(T& t);
};
template <typename T>
void A::print(T& t) {
// do sth specific for A
}
template <typename T>
struct B : A {
virtual void print(T& t);
};
void B::print(T& t) {
// do sth specific for B
}
选项二:抽象方法,如果用户不提供实现,代码将无法编译。
template <typename T>
struct A {
virtual void print(T& t)=0;
};
template <typename T>
struct B : A {
virtual void print(T& t){
// do sth specific for B
}
};
template <typename T>
void B::print(T& t){
// do sth specific for B
}
除了上面提到的,如果您不使它们成为虚的,派生类将会遮蔽基类方法,这肯定不是您想要的。因此,不可能的。
我的问题是如何使用单个指针指向不同的A或B对象。
您可以在没有虚函数本身的情况下做到这一点。但是你真正要做的是编写一个v表和虚函数的实现。
如果我要手动实现虚函数,我会将其全部基于Boost。变体对象。该变体将有效地保存每个类的成员数据。要调用函数,可以使用一个变体访问函子。每个"虚函数"都有自己的访问函子,对于变体中每种可能的类型,该访问函子都有不同的operator()重载。
所以你可以这样写:
typedef boost::variant<StructA, StructB, StructC> VirtualClass;
可以在变量中存储这些对象中的任何一个。您可以像这样调用对象上的"虚函数":
VirtualClass someObject(StructA());
boost::apply_visitor(FunctorA(), someObject);
FunctorA类是你的虚函数实现。它是一个访问者,定义如下:
class FunctorA : public boost::static_visitor<>
{
void operator()(StructA &arg){
//Do something for StructA
}
void operator()(StructB &arg){
//Do something for StructB
}
void operator()(StructC &arg){
//Do something for StructC
}
}
访问者可以有返回值,这些返回值由apply_visitor
返回。它们可以接受实参,方法是将实参存储为visitor类的成员。等等
最好的是,如果你曾经改变你的变体类型,添加新的"派生类",你将得到编译器错误的任何函数没有重载的新类型。
但说实话,你应该只使用虚函数
通过使用CRTP(奇怪的重复模板模式),您可以实现静态多态,而不需要虚拟。
#include <iostream>
using namespace std;
#define MSG(msg) cout << msg << endl;
template<class Derived>
class Base{
public:
void print()
{
static_cast<Derived*>(this)->print();
}
};
class Derived1 : public Base<Derived1>
{
public:
void print()
{
MSG("Derived 1::print");
}
};
class Derived2 : public Base<Derived2>
{
public:
void print()
{
MSG("Derived 2::print");
}
};
template<class T>
void callme(Base<T>& p)
{
p.print();
}
int main()
{
Base<Derived1> p1;
Base<Derived2> p2;
callme(p1);
callme(p2);
system("pause");
return 0;
}
//Result :
//Derived 1::print
//Derived 2::print
相关文章:
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- N-queen问题:无法弄清楚为什么我的解决方案不起作用
- 这是另一个虚拟模板解决方案
- 寻找c++成员函数覆盖(非虚拟)的解决方案
- 虚拟模板解决方案