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相同的方式表达模板参数的条件,并以简洁,优雅和直观的方式解决问题.
我知道如何做到这一点是Java,但我仍然不熟悉C++语法.问题非常类似于某些集合只能采用实现Comparable的模板变量.然后标题看起来像
public class Calendar<D extends Date>{
...
}
Run Code Online (Sandbox Code Playgroud)
确实,这是同样的问题,在C++中,通常通过忽略它来解决.为什么我们需要强制执行对象必须实现的IComparable
?在Java中,由于其贫血型系统,它是必要的.没有这个约束,我们将无法比较对象.
在C++中,规则是不同的.容器只是尝试比较它们存储的对象,如果类型不支持它,则会出现编译错误.不需要接口或继承.
而且你通常会在Calendar
课堂上做同样的事情.只是不强制执行 "必须子类形式Date
约束".
而是指定类型必须公开的成员,以及应该从中获取什么语义(如果有的话).
例如,如果您的日历尝试执行以下操作,则对于日期对象d0
和d1
:
d0.getDay();
d0.getTime();
Time t = d0 - d1;
Run Code Online (Sandbox Code Playgroud)
那些是应该支持的操作.支持这些操作的任何类是一个有效的Date类,即使它没有继承任何东西.
您正在寻找的是模板参数的概念检查.这些已成为下一个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多态性有什么问题,你想使用模板的编译时多态?