MGA*_*MGA 5 c++ polymorphism templates crtp
virtualC ++ 的主要优点之一是能够使用基类(指针或引用)来调用派生方法。
我正在阅读使用CRTP实现静态多态性的知识,但是我不明白如何使用该技术实现上面提到的内容,因为Base当需要模板时,我无法将函数声明为采用类型。
在我看来,仅通过使用函数重载就可以实现本文中描述的内容,因此,我敢肯定,该技术必须有更多的功能。
(PS:在回答该问题的评论中提到了这个确切的问题,但不幸的是没有人回答:“ vtables真正提供的功能是使用基类(指针或引用)来调用派生方法。您应该在此处显示如何使用CRTP进行操作。”)
这是我的最小代码,它给出错误“在'&'令牌无效Print(Base&Object)之前缺少模板参数”。
#include <cstring>
#include <iostream>
template <typename Derived>
struct Base
{
std::string ToStringInterface() { return static_cast<Derived*>(this)->ToString(); }
std::string ToString() { return "This is Base."; }
};
struct Derived : Base<Derived>
{
std::string ToString() { return "This is Derived."; }
};
void Print(Base& Object)
{
std::cout << Object->ToStringInterface() << std::endl;
}
int main()
{
Derived MyDerived;
// This works, but could have been achieved with a function overload.
std::cout << MyDerived.ToStringInterface() << std::endl;
// This does not work.
Print(MyDerived);
}
Run Code Online (Sandbox Code Playgroud)
好吧,你需要声明 print 一个模板函数:
template<class T>
void Print(Base<T>& Object)
{
std::cout << Object.ToStringInterface() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
感谢收到的评论和答案,我正在发布我的实现,以防它对其他人有用。
#include <cstring>
#include <iostream>
template <typename Derived>
class Base
{
public:
std::string ToStringInterface()
{
return static_cast<Derived*>(this)->ToString();
}
};
template<>
class Base<void> : public Base<Base<void> >
{
public:
std::string ToString()
{
return "This is Base (default implementation).";
}
};
class Derived : public Base<Derived>
{
public:
std::string ToString()
{
return "This is Derived.";
}
};
template <typename T>
void Print(Base<T>& Object)
{
std::cout << Object.ToStringInterface() << std::endl;
}
int main()
{
int Decision;
std::cout << "Do you want to create an object of type Base (input 0) or Derived (input 1)? ";
std::cin >> Decision;
if (Decision == 0)
{
Base<void> MyBase;
Print(MyBase);
}
else
{
Derived MyDerived;
Print(MyDerived);
}
}
Run Code Online (Sandbox Code Playgroud)