2017-05-06 16 views
0

タイムラインアプリケーションを作成しています。タイムラインは、TimelineItemを持つことができます。アイテムが繰り返される場合は、TimelineItemにTimelineItemRepeat型のベクトルを保持し、TimelineItemとTimelineItemRepeatの値の唯一の違いは開始時刻と終了時刻です。全く同じ変数を持つ2つのオブジェクトを作成する

このように、私は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

私はこれについて間違った方法をとっていますか?

私ははいと言います。同じオブジェクトを参照するためにベクトル内の複数の位置を取得しようとしているようです。これは、ポインタTimelineItemのベクトルを作成することによって簡単に達成できます。このようにして、単一ベクトルを持つことができます。timelineと呼んでください。

ポインタが何であるか、どういうふうに動作しているのかわからない場合は、これ以上のC++に取り組む前にそれらについて学んでください。

同じタイムラインアイテムをベクターで3回繰り返したいとしましょう。最も基本的な設定は、次のようになります。今

//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]に表示されます。これらはオブジェクトではなくポインタなので、->のinstaedを.にしてメンバーにアクセスする必要があります。

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++がどのように最良に書かれているかについてです。

編集:コメントに基づいて

、あなたが実際に必要とすると、2つの別々のクラス、タイムラインのアイテムを格納するためのイベントと1を表現するためのものです。単純な例:

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のベクトルを含むいくつかの情報を保持するオブジェクトTimelineを保持するオブジェクトUserを持っているということです。 – Beardo

+0

@Beardo Ah、あなたは2つの独立した構造体/クラスが必要です。"Dinner with team")と1つは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); 

コード内の唯一の違いは、あなたが->インを使用しなければならないということになりますこの文の.のティード:

関連する問題