2017-05-06 69 views
0

我在制作时间轴应用程序。时间轴可以有一个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 

我要对这个错误的方式?

+3

请显示一些代码! – OldProgrammer

+1

对我来说,您应该创建一个TimelineItem **指针**的向量,以便重复的条目引用内存中的同一个对象。 – ApproachingDarknessFish

+0

@OldProgrammer新增。据我所知,它的原因是TimelineItem正在创建自己的变量实例,在driver.cpp的顶部声明,所以创建一个新地址,而TimelineItemRepeat只是获取变量的地址。因此,如果我要更改driver.cpp中的变量,则TimelineItemRepeat会更新。 我只是不知道如何TimelineItem的数据域的位置传递给TimelineItemRepeat。 – Beardo

回答

2

我该怎么做呢?

我会说是。看起来你正试图在矢量中获取多个位置来引用同一个对象。这可以通过创建指针TimelineItems的矢量来容易地实现。这样我们可以有一个单独的矢量,称之为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]显示出来,因为它们都指向同一个对象。由于这些是指针,而不是对象,因此您必须使用->,例如.才能访问成员,例如。

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_itemtimeline做,你需要清理你new早期分配的内存:

delete tl_item; //destroys the object; all pointers now point to garbage memory. 

这将非常简单的程序工作,但我强烈建议考虑std::shared_ptr如果你关心人关于现代C++如何写得最好。

编辑:根据意见,你真正需要的是两个独立的类,一个代表事件和一个存储时间轴项

。简单的例子:

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") 

我留下了很多这里的代码,以使之明确的设置是什么。希望它的工作原理很清楚。

+0

感谢您的深入回复。非常感激。这种方法非常好,希望我需要每个TimelineItem的开始时间和结束时间不同,例如, UNIX时间戳。除此之外,我目前的流程是,我有一个对象用户持有一个对象时间轴,其中包含一些信息,包括TimelineItems的向量。 – Beardo

+0

@Beardo Ah,在我看来,你需要两个独立的结构/类,一个存储事件(即,“与团队共进晚餐”),一个存储TimelineItem,并为每个TimelineItem提供一个时间戳和一个指向Event对象的指针。我会想出一些示例代码。 – ApproachingDarknessFish

+0

感谢您的额外编辑!今天我会有一些时间来给这个测试。我会告诉你如何去。 – Beardo

0
repeats.push_back(TimelineItemRepeat(type, desc, loc, start, end, tl_item)); 

上述行向量创建全新的对象(完全独立的),只需复制你的价值观,所以如果你想要的值更新,你应该申报重复的指针的载体TimelineItem的:

vector<TimelineItem*> repeats; 

然后,而不是添加对象,你shold添加对象的地址:

TimelineItem tl_item(type, desc, loc, start, end); 
repeats.push_back(&tl_item); 

在你的代码唯一的区别是,你必须使用->插件在此声明中的.的泪滴:

std::cout << tl_item.getLinkedItems()[0]->toString() << endl; 
相关问题