当我的程序启动时,我希望它立即填写“日历”类,其中包含从18/1年1月1日到2011年12月31日的所有年/月/日。我在创建这个“日历”课时遇到了麻烦,我真的不知道我对C ++的选择是什么。
实现这一目标的最佳方法是什么?日/月/年应该是多图,如果是;如何有效地使用该多图来实现我想要做的事情(多图甚至可以容纳多于2个对象?)?或者这个类可能根本不应该是一个类,但整个事情应该变成一个多图?
我以“日历”项目为例,但我认为我的问题归结为: “我如何设计一个可以容纳多层数据的类(或替代),这些数据链接且易于控制/访问”。
通过'控制',我的意思是添加/删除/检查 - 如果已经存在等等。
所以也许这样的事情(忽略我在图片中的例子):
calendar.addYear(1998) //Add 1998 to the year stack (array?) inside the "calendar" object.
calendar.addMonth(1,0) //Add month 1 (january) to month stack (array?) keeping year-array position 0 as a reference, so we know what year this month belongs to.
calendar.addDay(1,0) //Add day 1 to day stack (array?) keeping month-array position 0 as a reference, so we know which month this day belongs to.
我希望用这样的类以编程方式实现的一个例子是:
//This is a magical GUI object I just made up ;D
myGUIofChoiceCreateSomeGUIobject GUIobject;
int i;
for(i=0; i < calendar.yearCount; i++;)
{
GUIobject.addYeartoGUIobject(calendar.year[i]); //Add current year to our GUI. The user can now select it, hooray!
addMonthsToYear(i); //Add months belonging to this year to our GUI.
}
addMonthsToYear(int theYear)
{
int i;
for(i=0; i < calendar.year[theYear].monthCount; i++;)
{
/*
Our made-up GUI will add the current month to the year we received as an
argument. As long as that year is selected in the GUI, our user can pick this month,
hooray!
*/
GUIobject.addMonthToGUIobject(calendar.year[theYear].month[i])
addDaysToMonth(i,theYear) //Add days to this month (not typing this one down, you can see where this is going)
}
}
好像所有这一切都不够复杂;什么是没有待办事项的日历?所以“calendar.day”需要链接到数组/多图/任何对象,它们可能如下所示:
struct stuffToDo{
std::string message;
float time;
}
之后,应该很容易将类似的对象添加到类中:
stuffToDo newstuff;
newstuff.message = "Find a C++ tutor so you can stop bothering stackoverflow";
newstuff.time = 15.20;
calendar.year[2012].month[11].day[18].addObject(newstuff);
我很茫然,我有什么选择?
PS。我很抱歉我的例子之间存在不一致,但如果不知道我应该做什么,这是不可避免的,这就是这个问题的本质。
答案 0 :(得分:2)
提升图书馆是您需要查看的内容..
为了帮助自己,你可以找到 你想在这里制作日历课程 的 http://sourceforge.net/projects/c-cpp-calender/ 强>
答案 1 :(得分:1)
我认为你需要退后一步,清楚地思考你想做什么。什么是关键的抽象?您想要支持哪些操作和操作?写一篇关于系统使用的故事。在这个故事中,重要的名词通常成为C ++代码中的对象,重要的动词成为方法。
看起来您希望您的数据结构跨越多年,但基本对象是Day,它有一个数字并且是Tasks的容器,每个任务都有一条消息和一个与之关联的时间。然而,一天属于一个月和一年。现在几个月和几年可能只是一天的属性,或者它们可能是自己的完整对象(月和年)。在第二种方法中,月份(也有名称)是天的容器,而年份(也有数字)是月份的容器。
如果您有多年和几个月只是属性,您可能希望主日历类中的数据结构映射多年到几天,一个映射年和月组合到天。如果您使用月份和年份的对象,那么在顶层您将只有一个Year对象列表,或者可能是将年份数字映射到Year对象的地图。为了到达特定的一天,您只需从年份编号,月份名称和日期编号开始,然后在树中导航直到您到达那一天,也许您可以随时创建对象。
当然,如果您将基本对象设置为具有日,月和年属性的任务,则所有这些可能会变得更简单一些。这些将存储在地图中,其中键是年,月和日的序列化。如果地图确实是一个多图,那么每年/每月/每天组合可能有多个任务。 Task对象本身可以生成这个序列化的密钥,它提供了良好的信息隐藏和解耦,尽管让类通过静态方法而不是特定对象生成它可能更灵活。此多图表成为Calendar对象的核心。它也很有效,因为结构的总大小随着任务的数量而增长,而不是跨越的时间量,只要您可以优雅地处理没有相关任务的年/月/日组合的查找。要渲染日历,只需迭代年,月和日,然后在日历中查找任务。
所有这些都归结为您需要认真思考数据模型这一事实。我发现一旦找到一个好的数据模型,实际编码就差不多了。没有明确的数据模型会导致大量的错误启动和混乱的代码。查看统一建模语言(UML)符号并用铅笔和纸绘制一些图片。我觉得事情会更加清晰。