首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++:多态类模板

C++:多态类模板
EN

Stack Overflow用户
提问于 2009-10-11 10:32:24
回答 6查看 3.4K关注 0票数 5

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

代码语言:javascript
复制
template<typename D> class Calendar{ 
    ...
}

但我突然意识到,D现在实际上可以是任何类。现在我的问题是,如何确保D是date对象的子类?

我知道怎么做是Java,但我仍然不熟悉C++语法。这个问题非常类似于一些集合只能接受实现可比较的模板变量。标头看起来就像这样

代码语言:javascript
复制
public class Calendar<D extends Date>{
     ...
}

-编辑:

模板参数定义日历引用的实际日期。不同的日期类型以不同的格式表示同一天。例如,如果我创建了一个Calendar<Gregorian>,它将能够获取另一种Date格式的日期,比如儒略历,或者任何其他日期格式,并以公历格式表示它们。这样就可以在不同日期格式的日历之间进行转换。因此,如果我有一个Calendar<Gregorian>,我可以很容易地将它转换为Calendar<Julian>。那么以下情况是可能的:

代码语言:javascript
复制
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;

和输出:

代码语言:javascript
复制
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

-新编辑:

最后一次编辑现在更有意义了。我对格式有一点不同。

谢谢你所有的答案。

我是一名计算机科学专业的大三学生,我想说我对OO和多态等相关概念相当熟悉。这篇文章的目的是找出在C++中是否有一种方法可以像Java语言一样表达模板参数的条件,并以简洁、优雅和直观的方式解决问题。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-10-11 11:14:23

我知道怎么做是Java,但我仍然不熟悉C++语法。这个问题非常类似于一些集合只能接受实现可比较的模板变量。标头看起来就像这样

代码语言:javascript
复制
public class Calendar<D extends Date>{
     ...
}

诚然,这是同样的问题,在C++中,通常通过忽略它来解决它。为什么我们需要强制要求对象必须实现IComparable?在Java中,它是必要的,因为它的类型系统很弱。如果没有这个约束,我们将无法比较对象。

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

您通常会在Calendar类中执行相同的操作。简单地说,不要强制执行“必须子类形式的Date”约束。

相反,应指定该类型必须公开的成员,以及应从这些成员中预期的语义。

例如,如果日历尝试对date对象d0d1执行以下操作

代码语言:javascript
复制
d0.getDay();
d0.getTime();
Time t = d0 - d1;

那么这些就是应该支持的操作了。任何支持这些操作的类都是有效的Date类,即使它没有子类。

票数 9
EN

Stack Overflow用户

发布于 2009-10-11 10:45:01

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

在语言本身没有概念的情况下,有一些库试图做到这一点,但希望概念检查成为核心语言的一部分的原因是,如果没有语言支持,几乎不可能实现概念检查。

不过,在您的具体示例中,这应该不会太难。例如,您可以在基类中放入一些特殊的typedef并进行检查:

代码语言:javascript
复制
class date {
  public:
    typedef int is_derived_from_date;
};

template<typename D> class Calendar{ 
    typedef typename D::is_derived_from_date blah;
    ...
};

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

然而,说了这么多,我不得不质疑你的设计。如果你想使用模板的编译时多态性,那么普通的OO多态性有什么问题?

票数 8
EN

Stack Overflow用户

发布于 2009-10-11 10:37:14

我认为您的问题不需要使用模板就可以解决。D总是Date的派生类,那么为什么不只有Date对象的集合呢?

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1550370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档