我正在制作时间轴应用程序。时间轴可以有一个TimelineItem。如果一个项目重复,我希望TimelineItem包含一个TimelineItemRepeat类型的向量,其中TimelineItem和TimelineItemRepeat中值之间的唯一差异是开始和结束时间。
因此,每当我对TimelineItem的实例进行编辑时,我都希望这样做。 tl_item.setLocation(“Paris”),与TimelineItem相关的所有TimelineItemRepeat实例也将更新。
我试图通过创建TimelineItem实例然后将每个TimelineItem变量的内存位置传递给TimelineItemRepeat的构造函数来实现此目的。
目前,我正在声明变量并将其传递给我的两个构造函数,但是,它无法正常工作。我的代码:
driver.cpp
short int type = 0;
string desc = "Lunch with Team";
string loc = "New York Office";
time_t start = time_t(0);
time_t end = time_t(600);
vector<TimelineItemRepeat> repeats;
TimelineItem tl_item(type, desc, loc, start, end);
repeats.push_back(TimelineItemRepeat(type, desc, loc, start, end, tl_item));
tl_item.setLinkedItems(repeats);
std::cout << tl_item.toString() << endl;
std::cout << tl_item.getLinkedItems()[0].toString() << endl;
tl_item.setDescription("Dinner with Team");
std::cout << tl_item.toString() << endl;
std::cout << tl_item.getLinkedItems()[0].toString() << endl;
输出
TimelineItem Description Address: 0x7fff5ebcb600
0 Lunch with Team 0 600 1
TimelineItemRepeat Description Address: 0x7fff5ebcb6a0
0 Lunch with Team 0 600
TimelineItem Description Address: 0x7fff5ebcb600
0 Dinner with Team 0 600 1
TimelineItemRepeat Description Address: 0x7fff5ebcb6a0
0 Lunch with Team 0 600
我是以错误的方式解决这个问题吗?
答案 0 :(得分:2)
我是以错误的方式解决这个问题吗?
我会说是的。看起来你正试图在向量中获得多个位置来引用同一个对象。这可以通过创建指针到TimelineItem
的向量来轻松完成。这样我们就可以有一个向量,称之为timeline
。
如果您不知道指针是什么或它们如何工作,请在处理更多C ++之前了解它们。
假设我们希望在我们的向量中重复相同的时间轴项目三次。在最基本的情况下,设置看起来像这样。
//Create a pointer to a dynamically allocated object
TimelineItem *tl_item = new TimelineItem(type, desc, loc, start, end);
vector<TimelineItem*> timeline; //vector of pointers instead of objects.
//all entries point to the same object
timeline.push_back(tl_item);
timeline.push_back(tl_item);
timeline.push_back(tl_item);
现在,您对timeline[0]
所做的任何更改都会显示在timeline[1]
和[2]
中,因为它们都指向同一个对象。由于这些是指针,而不是对象,因此您必须使用->
.
的{{1}}来访问成员,例如。
tl_item->setDescription("Dinner with team");
与
具有相同的效果timeline[0]->setDescription("Dinner with team");
timeline[1]->setDescription("Dinner with team");
timeline[2]->setDescription("Dinner with team");
但是,使用指针意味着我们现在需要担心内存分配。完成tl_item
和timeline
后,您需要使用new
清理之前分配的内存:
delete tl_item; //destroys the object; all pointers now point to garbage memory.
这适用于非常简单的程序,但如果您完全关心现代C ++的编写方式,我强烈建议您查看std::shared_ptr。
编辑:
根据评论,您实际需要的是两个单独的类,一个用于表示事件,另一个用于存储时间轴项。简单的例子:
class Event {
string description;
};
class TimelineItem {
Event *event;
timestamp time; //however you want to store this
//whatever constructors, getters, setters you need
};
vector<TimelineItem> timeline;
Event *dinner = new Event("Dinner with team");
//Let's say we have dinner twice this week. Set these to whatever.
timestamp first_item_ts = ... ;
timestamp second_item_ts = ... ;
//Two separate items in the timeline, at different timestamps, but both refer to the same Event object using pointers!
timeline.push_back(TimelineItem(dinner, first_item_ts));
timeline.push_back(TimelineItem(dinner, second_item_ts));
现在,如果我们更改公共事件对象,则两个时间轴项都会显示它。以下所有都具有相同的效果:
timeline[0].event->setDescription("Breakfast with team")
timeline[1].event->setDescription("Breakfast with team")
event->setDescription("Breakfast with team")
我在这里遗漏了很多代码,以便明确设置是什么。希望它的工作原理很清楚。
答案 1 :(得分:0)
repeats.push_back(TimelineItemRepeat(type, desc, loc, start, end, tl_item));
上面的行在向量中创建全新的对象(完全独立),只复制你的值,所以如果你想要更新值,你应该将重复声明为指向TimelineItem的指针的向量:
vector<TimelineItem*> repeats;
然后,不是添加对象,而是添加对象的地址:
TimelineItem tl_item(type, desc, loc, start, end);
repeats.push_back(&tl_item);
您的代码中唯一的区别是您必须在此声明中使用->
而不是.
:
std::cout << tl_item.getLinkedItems()[0]->toString() << endl;