c++:重写父类中的模板成员函数
c++: override template member function in parent class
假设我有这样一个类结构:基类Object
,它是Bool
、Int
、Float
、Bytes
和Unicode
类的父类。以前,我在Object
类和所有子类中有一些函数,如Bool cast_bool() const
、Int cast_int() const
等作为虚拟函数,我已经分别实现了这些函数。
似乎更好的解决方案是实现template <typename TYPE> TYPE cast() const
函数。然而,由于C++禁止虚拟模板函数,我不知道如何才能完成这项任务。我需要的是为Object
及其子代提供template <typename TYPE> TYPE cast() const
。泛型Object::cast<TYPE>() const
将只抛出CastError
;然后对于每种类型,如Bool
、Int
等,我将实现Bool::cast<Bool>() const
、Int::cast<Bool>() const
等函数。我甚至计划向内置对象添加强制转换,尽管现在我只是重载operator bool() const
、operator signed short() const
等。如果没有实现,模板必须从Object
类切换到其泛型形式,只会抛出一个错误。有没有办法做到这一点(也许我需要使用一些模式)?或者更容易离开像Int cast_int() const
这样的函数?提前感谢!
像下面的例子一样添加一个中间类,或者只使用dynamic_cast
而不使用任何模板方法。
#include <iostream>
#include <string>
using namespace std;
template <class> class ObjectImpl;
class Object
{
public:
virtual ~Object() {}
template <class T>
T cast() const
{
if (auto obj = dynamic_cast<const ObjectImpl<T>*>(this))
{
return obj->cast();
}
else
{
throw std::string("cast error");
}
}
};
template <class T>
class ObjectImpl : public Object
{
public:
virtual T cast() const = 0;
};
class Bool : public ObjectImpl<bool>
{
public:
bool cast() const override { return true; }
};
class Float : public ObjectImpl<float>
{
public:
float cast() const override { return 12.34f; }
};
int main()
{
Object* obj = new Float;
cout << obj->cast<float>() << endl;
try
{
cout << obj->cast<bool>() << endl;
}
catch (std::string e)
{
cout << e << endl;
}
return 0;
}
您正在做的事情听起来不是一个好主意,C++不是Java或C#。。。尽管如此,你还是可以这样做:
class Object
{
public:
template<typename T>
T& cast()
{
return cast_impl(std::declval<T>());
}
private:
virtual bool& cast_impl(bool&){ throw std::bad_cast(); }
virtual int& cast_impl(int&){ throw std::bad_cast(); }
};
class Boolean : public Object
{
bool value_;
public:
private:
bool& cast_impl(bool) override
{
return value_;
}
};
您可以保留一组标志
enum Castablity{
intable = 0x1,
floatable = 0x2,
doubleable = 0x4,
bytable = 0x8,
stringable = 0x10,
unicodable = 0x20,
};
并在每个类中保留一个virtual int castable() const
函数,例如您的Int::castable()
将返回intable | floatable | doublable | stringable
。并且YOu需要有另一个模板化映射,该映射采用Castablity枚举值并在typedef中返回目标类型。
template <typename T>
struct type_value;
template <enum v>
struct value_type;
template <>
struct type_value<Int>{
enum {value = intable;}
};
template <>
struct value_type<intable>{
typedef Int data_type;
};
和全局投射函数
template <typename T, typename U>
U cast(const T& original){
if(!original.castable(type_value<U>::value))
//throw exception
return detail::cast<U>(original.internal_data());
}
您可以有一个虚拟方法,它采用整数值,而不是在编译时采用类型。或者您可以有一个内部结构来存储所有类型的对象值。类似boost::any
您可以编写另一个专门化的详细名称空间,将该内部类型转换为目标类型
namespace detail{
template <typename T>
/// you may have specialization for different types
struct casting_helper{
static T cast(const internal_type& data){
}
}
template <typename T>
T cast(const internal_data& data){
return casting_helper<T>::cast(data);
}
}
如果您对运行时强制转换很满意,另一种选择。
class Object
{
public:
template<typename T>
T& cast()
{
return *dynamic_cast<T*>(get());
}
private:
virtual void* get() = 0;
};
class Boolean : public Object
{
bool value_;
public:
private:
void* get() override
{
return &value_;
}
}
您可以为对象创建一个类型包装器。
struct TypeWrapperBase
{
protected:
static int m_counter;
};
int TypeWrapperBase::m_counter = 0;
template<typename T>
struct TypeWrapper:
TypeWrapperBase
{
static int m_type;
protected:
static int AllocateType()
{
m_counter++;
return m
}
public:
static int GetType()
{
return m_type;
}
};
template<typename T>
int TypeWrapper<T>::m_type = TypeWrapperBase::m_counter++;
void main()
{
std::cout << TypeWrapper<int>::GetType() << std::endl; // prints 0
std::cout << TypeWrapper<float>::GetType() << std::endl; // prints 1
std::cout << TypeWrapper<bool>::GetType() << std::endl; // prints 2
}
现在,通过这种方式,您可以通过比较el1.GetType()和el2.GetType(
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法