2017-07-10 6 views
1

私はちょうどC++をダウンさせようとしています。私は自分自身のライブラリとそれ以外のものを作る必要があります。だから、JDKのListクラスとまったく同じ、自分自身のListテンプレートクラスの初めを取得しようとしています。だから私はテンプレートを取得して、私はちょうど私がリストオブジェクトの内容をループすることができるようにする方法を知りたいです。この方法で、私は上記のオブジェクトの内容を印刷することができます。私はどこから始めるべきか正確には分かりません。C++のカスタムリストをループする方法

#pragma once 

template<typename T> class List { 
public: 
    List() : _size(0), _elements(nullptr) {} 
    ~List() { 
     if (_elements != nullptr) { 
      delete[] _elements; 
     } 
    } 

    inline int size() { return _size; } 

    inline void add(T element) { 
     _size++; 

     T* buffer = new T[_size]; 

     if (_elements != nullptr) { 
      memcpy(buffer, _elements, sizeof(T) * (_size - 1)); 
      delete[] _elements; 
     } 

     buffer[_size - 1] = element; 
     _elements = buffer; 
    } 

    inline void remove(T element) { 
     _size--; 

     T* buffer = new T[_size]; 

     if (_elements != nullptr) { 
      memcpy(buffer, _elements, sizeof(T) * _size); 
      delete[] _elements; 
     } 
     else { 
      assert(false); 
     } 

     _elements = buffer; 
    } 

    inline T* getElements() { 
     return _elements; 
    } 
private: 
    int _size; 
    T* _elements; 
}; 

そして、これはループのために、私はそれは、Javaのように拡張forループであることに慣れている

#include <cstdio> 
#include <string> 

#include "List.h" 

using namespace std; 

int main(int argc, char ** argv) 
{ 
    string str = "This is a test!"; 
    List<char> list = breakString(str); 
    for (char c : list.getElements()) { 

    } 
    getchar(); 
    return 0; 
} 

List<char> breakString(string str) { 
    List<char> list; 
    for (char c : str) { 
     list.add(c); 
    } 
    return list; 
} 

だから私は何を把握しようとしているが、その中で私のメインのCPPファイルです、それはここでC++と同じですか?もしそうなら、私はどのようにしてこのオブジェクトを反復可能にしますか?

私が直接尋ねた場合、私は私の質問にもっと正確な答えを得ると思った。 range_expressionが始まるという名前のメンバーを持つクラス型Cの発現がある場合Range-based forを検証するため

+1

可能な重複[「ループの範囲ベース」で動作するように私のカスタム型を作成する方法?](ht tps://stackoverflow.com/questions/8164567/how-to-make-my-custom-type-to-work-with-range-based-for-loops) – Azeem

答えて

1

ガイドラインはhttp://en.cppreference.com/w/cpp/language/range-for

で見つけることができ、および/またはタイプに関係なくメンバー名前端(またはそのメンバーのアクセシビリティ)、begin_exprは__range.begin()、end_exprは__range.end()です。要するに

あなたのデータは、生の配列であることから、あなたはList<T>

T* begin() { return _elements;} 
T* end() { return _elements + _size;} 

あなたのクラスにこれらパブリックメソッドを追加する必要があります。そして、あなたは、オブジェクトに範囲ベースforを呼び出すことができます直接:

for (char c : list) 

あなたのコードに他の問題があります。そのうちの1つ(確かに唯一のものではない)は、breakStringがオブジェクトを返しますが、あなたのクラスは簡単ではなく、copyまたはmoveコンストラクタを定義していません。

この回答は、あなたのクラスにRange-based forを有効にする方法についての「主な」質問を扱っています。それはちょうど必要と二つの方法が(実際のイテレータまたは連続したメモリチャンクへのポインタ可能性」)イテレータのように見える何かを返すbegin()end()

あなたはこのように、breakStringを使用せずに、提案の修正をテストすることができます:

int main(int argc, char ** argv) 
{ 
    std::string str = "This is a test!"; 
    List<char> list; 
    for (char c : "abcdef") { list.add(c); } 

    for (char c : list) { std::cout << c << "\n"; } 
} 

そして、それは「完全に反復可能な」あなたはieratorと呼ばれる入れ子になったクラスを定義することができます定義するようにする。..の

関連する問題