6

私は専門家レベルの Java プログラマーで、自分の知識を C++ に移植しようとしています。これは宿題ではなく、C++ に相当するものを学ぼうとしている概念にすぎません。

私がやろうとしているのは、ループを使用してカスタムタイプのオブジェクトのリストを「生成」することです。これは私が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++ のスコープとループについて多くのことを読みました。私は両方で何かを見つけることができないようです。

4

2 に答える 2

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();
于 2013-11-04T23:53:43.623 に答える
1

理想的な答えは非常に悪い考えを示唆しています - ループ内のイテレータでポストインクリメント ++ を使用してください。postincrement は、インクリメントする前にイテレータが持っていた値を返す必要があるため、反復のみが必要なループでは絶対に使用しないでください。そのため、以前の値を以前のどこかにコピーする必要があります。パフォーマンスの観点からは良くなく、悪いコードスタイルの兆候です.

于 2013-11-05T00:45:56.760 に答える