2013-11-04 19 views
5

私は、知識をC++に移植しようとしている、熟練したレベルのJavaプログラマです。これは宿題ではなく、私がC++の等価物を学ぼうとしているコンセプトです。私がやろうとしている何C++ - std :: vectorにオブジェクトを追加する、ループでインスタンス化する

、ループを使用して、カスタムタイプのオブジェクトのリスト「を生成」です。これは私がJavaでやる方法です:

public class TestClass 
{ 
    private ArrayList<ExampleClass> _exampleObjects; 
    private int _numObjects = 10; 

    public void populateList() 
    { 
     _exampleObjects = new ArrayList<ExampleClass>(); 

     for(int i = 0; i < _numObjects; i++) 
     { 
     _exampleObjects.add(new ExampleClass()); 
     } 
    } 

    public void doStuffWithListItems() 
    { 
     for(ExampleClass e : _exampleObjects) 
     { 
     e.performAction(); 
     } 
    } 
} 

非常に単純なもの。リストを作成し、任意のループを繰り返してオブジェクトを追加します。次に、これらのオブジェクトをループし、目的に合わせて使用​​します。

TestClass.h:

class TestClass 
{ 
    public: 
     // Constructor, copy constructor, destructor definitions 

     void populateList(); 
     void doStuffWithListItems(); 
    private: 
     std::vector<ExampleClass> _exampleObjects; 
     const int _numObjects = 10; 
}; 

TestClass.cpp:

void TestClass::populateList() 
{ 
    for(int i = 0; i < _numObjects; i++) 
    { 
     ExampleObject obj; 
     _exampleObjects.push_back(obj); 

     /* What actually goes here in place of obj? */ 
    } 
} 

void TestClass::doStuffWithListItems() 
{ 
    for(auto it = _exampleObjects.begin(); it != _exampleObjects.end(); it++) 
    { 
     /* What do i do with my iterator to access my object? */ 
    } 
} 

その私が最初のループで私のオブジェクトを初期化する場合、それらはスコープの外に出ると、年末までに死ぬことを私の理解各ループ反復のそうですか?その場合、永続的なインスタンスを作成するにはどうすればよいですか?

私はshared_ptr <>を使って実験しましたが、それらを永続的に保存することはできましたが、私の人生ではshared_ptrのイテレータから参照を外す方法はありませんでした。<>

本当にシンプルなコンセプトになるはずです。私はちょうどそれを解決するように見えることはできません。私はC++スコープとループで多くを読んだことがあります。私は両方で何かを見つけることができないようです。

答えて

5
ExampleObject obj; 
_exampleObjects.push_back(obj); 

/* What actually goes here in place of obj? */ 

何もありません。 ExampleClassに作業コピーコンストラクタがあると仮定すると、正しいものです。あなたのコンパイラがC++ 11をサポートしている場合(少なくともautoを使用しているので、少なくとも部分的に)、あなた自身でコピーを保存することができます。

_exampleObjects.emplace_back(); 

これは、一致するコンストラクタ(この場合、デフォルトCTOR)の引数(この場合はなし)を転送する、ベクター内の所定位置にオブジェクトを構築します。イテレータからオブジェクトにアクセスするには、次のようにします。

for(auto it = _exampleObjects.begin(); it != _exampleObjects.end(); it++) 
{ 
    it->performAction(); 
} 

ここでも、C++ 11はここでより良いものを作ることができます。

for(auto & obj : _exampleObjects) 
{ 
    obj.performAction(); 
} 

その私が最初 ループ内で私のオブジェクトを初期化する場合、それらはスコープの外に出ると、各ループ反復の最後で死ぬことを私の理解。

正しい。

もしそうなら、どのように私は、永続的なインスタンスを作るのですか?

vector<>::push_backがこれを処理します。パラメータをベクトルにコピーします。言い換えれば、ループ内で作成されたオブジェクトと同じオブジェクトではなく、コピーです。 ExampleClassにコピーセマンティクスが壊れていないことを確認するだけです。あなたが共有ポインタのベクトルへのイテレータを持っていた場合

は私の人生のためのshared_ptr>

<

の イテレータから逆参照する方法を考え出すことができませんでした、(itそれを呼び出します)、あなたはそれをデリファレンスだろう、と保存されたオブジェクトのメンバ関数を呼び出して、次のように:

(*it)->performAction(); 
// alternatively 
(**it).performAction(); 
+0

ありがとうございました。これは理想的な答えです。 :D –

+0

@ScottDrew:コードの後に​​質問した質問を明確にするための追加情報を追加しました。 –

+0

ありがとうございます、余分な情報は本当に役立ちます。私は本当に実際のプロジェクトで実際に使用するためにC++を十分に把握し始めているように感じます。私は雷の速い答えのために十分にあなたに感謝できません。 –

1

理想的な答えは非常に悪い考えを示唆 - ループでイテレータにポストインクリメント++を使用します。 ポストインクリメントはインクリメントする前のイテレータの値を返さなければならないため、イテレートする必要があるループでは使用しないでください。前の値を以前のどこかにコピーする必要があります。 パフォーマンスの観点と悪いcodestyleのサインからは、それほどうまくいきません。

+0

あなたは良い点を作っています。ポストインクリメントを提案しているわけではありませんでしたが、私はOPのループをコピーしていただけでした。なぜなら、これは質問の内容ではないからです。 –

関連する問題