C++:多态类模板

mah*_*hju 5 c++ polymorphism inheritance templates

考虑一个存储一堆Date对象的类Calendar.日历旨在保存从Date继承的任何类型的对象的集合.我认为最好的方法是使用类模板,例如

template<typename D> class Calendar{ 
    ...
}
Run Code Online (Sandbox Code Playgroud)

但让我感到震惊的是,D现在实际上可以成为任何阶级.我现在的问题是,如何确保D是日期对象的子类?

我知道如何做到这一点是Java,但我仍然不熟悉C++语法.问题非常类似于某些集合只能采用实现Comparable的模板变量.然后标题看起来像

public class Calendar<D extends Date>{
     ...
}
Run Code Online (Sandbox Code Playgroud)

--------------------编辑:---------------------------- --------------

template参数定义日历引用的实际日期.不同的日期类型以不同的格式表示同一天.例如,如果我制作了Calendar<Gregorian>它,它将能够以其他Date格式拍摄日期,比如朱利安日历或任何其他日期格式,并以格里高利格式呈现它们.这样可以在不同日期格式的日历之间进行转换.所以,如果我有一个Calendar<Gregorian>我可以轻松地将其转换为Calendar<Julian>.那么以下是可能的:

Calendar<Gregorian> cal;
std::cout << "These events are entered as dates in 
    the Gregorian calendar" << std::endl;
cal.add_event("Christmas", 12, 25);
cal.add_event("Gregorian new year", 1, 1);
std::cout << cal << std::endl;
std::cout << "----" << std::endl;
std::cout << "And printed out as Julian dates" << std::endl;
Calendar<Julian>(cal);
std::cout << cal<< std::endl;
Run Code Online (Sandbox Code Playgroud)

和输出:

These events are entered as dates in the Gregorian calendar
2009-12-25 Christmas
2010-01-01 Gregorian new year
----
And printed out as Julian dates
2009-12-13 Christmas
2009-12-19 Gregorian new year
Run Code Online (Sandbox Code Playgroud)

-------------新编辑:----------------------

最后的编辑现在更有意义.我对格式有点不同意见.

感谢所有的答案.

我是第三年的计算机科学专业的学生,​​我会说我对OO和相关概念如Polymorphism等非常熟悉.这篇文章的目的是找出C++中是否存在一种方法.以与Java相同的方式表达模板参数的条件,并以简洁,优雅和直观的方式解决问题.

jal*_*alf 9

我知道如何做到这一点是Java,但我仍然不熟悉C++语法.问题非常类似于某些集合只能采用实现Comparable的模板变量.然后标题看起来像

public class Calendar<D extends Date>{
     ...
}
Run Code Online (Sandbox Code Playgroud)

确实,这是同样的问题,在C++中,通常通过忽略它来解决.为什么我们需要强制执行对象必须实现的IComparable?在Java中,由于其贫血型系统,它是必要的.没有这个约束,我们将无法比较对象.

在C++中,规则是不同的.容器只是尝试比较它们存储的对象,如果类型不支持它,则会出现编译错误.不需要接口或继承.

而且你通常会在Calendar课堂上做同样的事情.只是不强制执行 "必须子类形式Date约束".

而是指定类型必须公开的成员,以及应该从中获取什么语义(如果有的话).

例如,如果您的日历尝试执行以下操作,则对于日期对象d0d1:

d0.getDay();
d0.getTime();
Time t = d0 - d1;
Run Code Online (Sandbox Code Playgroud)

那些是应该支持的操作.支持这些操作的任何类一个有效的Date类,即使它没有继承任何东西.


sbi*_*sbi 8

您正在寻找的是模板参数的概念检查.这些已成为下一个C++标准草案的一部分,但几周/几个月前又被抛弃了.

如果没有正确的语言概念,有一些库试图这样做,但是想要将概念检查作为核心语言的一部分的原因是,在没有语言支持的情况下实现它们或多或少是不可能的.

在你的具体例子中,这不应该太难.例如,您可以将一些特殊内容typedef放入基类并检查:

class date {
  public:
    typedef int is_derived_from_date;
};

template<typename D> class Calendar{ 
    typedef typename D::is_derived_from_date blah;
    ...
};
Run Code Online (Sandbox Code Playgroud)

另一种方法是选择is_derived<B,D>::result在网络上浮动的任何模板元函数,并在Calender类中对此进行静态检查.Boost同时具有is_derived元函数和静态断言.

然而,说完这一切之后,我不得不质疑你的设计.普通的OO多态性有什么问题,你想使用模板的编译时多态?