2017-03-08 9 views
1

パフォーマンスは私がstd::experimental::dynarrayのように働く何か、そのサイズは、実行時に決定された配列を必要とする私のアプリケーションで実行時の固定サイズのstd :: vectorですか?

非常に重要です。

だから私はresizereserveまたはpush_backを呼び出すために、std::vectorのためのラッパークラスを使用して、すべての機能を与えることが、可能性のない考えました。いくつかの言葉では、サイズを変更するためのすべてのメソッド(私がそれらのいくつかを逃した場合は私を覚えてください)。

だから私はこのクラスを書き始めた:

CCVector.hpp

template <typename T> 
class CCVector{ 
public: 
    CCVector(size_t size); 
    T &operator[](typename std::vector<T>::size_type idx); 
private: 
    std::vector<T> v; 
}; 

CCVector.cpp

template<typename T> 
CCVector<T>::CCVector(size_t size) : v(size){} 
template<typename T> 
T& CCVector<T>::operator[](typename std::vector<T>::size_type idx){ 
    return v[idx]; 
} 

しかし、私は、私はstd::vectorことの再実装every方法に持っていると思った私は、この時点私は欲しい!たとえば、beginendsizeなど、私はそれらのすべてを実装する方法がわかりません...さらに、これはメンテナンスのためには本当に悪いです:私がstd::vectorから新しいメソッドが必要になると直ちにそれを再実装する必要がありますCCVector

これはすべて、実行時に固定サイズの配列が必要なためです。非標準のstd::experimental::dynarrayを使用せずにこれをどのように解決できますか?

+2

std :: vectorから継承するだけで、パブリックセクションで公開する各関数に対してusingステートメントを実行します。次に、無効にするすべての関数のprivateセクションでusingステートメントを実行します。 –

+1

また、[here](http://stackoverflow.com/a/15832431/4342498)からコードを使用することができます – NathanOliver

+0

@AlexZywicki、いいえ、それをしないでください。 [あなたは 'std :: vector'から継承しません](http://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from-stdvector)を参照してください。 –

答えて

6

プライベート継承を使用して、using宣言を使用して必要な関数をインポートして、クラスに必要な名前を導入します。

template<class T> 
class MyVector : private std::vector<T> 
{ 
public: 
    using std::vector<T>::end; 
    // etc 
}; 

(private継承を使用すると、ベクトルの問題は、ほとんどの人が標準コンテナから継承好きではない理由で仮想デストラクタを持っていない得ることはありません)

+1

これはまさに私が意味していたものです。 –

+0

これはパフォーマンス面で優れたソリューションですか?更新された質問に書いたように、アプリケーションではパフォーマンスが重要です – justHelloWorld

+1

@justHelloWorldこれは 'std :: vector'を使うのと同じくらい速くなります。 – Galik

0

あなたはstd::vectorが持っている権利ですあなたが外部に公開する必要がある非常にいくつかのメンバ関数ですが、多くはありません。たとえば、こちらをご覧くださいhttp://www.cplusplus.com/reference/vector/vector/

さらに、std::vectorを自分で再実装する必要はありません.STLのようなテストされた高速コードを使用するほうが、常に最適な方法です。

ので、代わりにそのように、外部に単に「前方」、機能を再実装の:

iterator begin() 
{ 
    return v.begin(); 
} 

これは定型コードのビットですが、あなたは非リサイズ機能に一度これを行う場合std::vectorの場合、完了です。

編集:

また、 std::vectorから継承しません。これは多くの理由から悪い考えです。

さて、私はここで少し速かったです。申し訳ありません。コメントとthis postが示唆しているように、STLコンテナから継承することは本質的に悪いことではありません。特に私的継承を使用する場合、それは与えられたタスクのための有効な解決策であるかもしれません。

+2

ベクターから継承することは多くの理由から悪い考えですか?誰もが "それをしないでください、それは悪いです"より詳細に説明したい理由はありません –

+1

@AlexZywickiかなり。私が見た主な理由は仮想破壊ですが、それは避けられます。 「ユーザーがクラスを使用する方法を知らない」のようなものは、これに固有のものではありません。 lucもしあなたがコンテナを継承している問題を_リストアップしているなら、OPは自分たちのケースで該当するかどうかを自分で決めることができます。 –

+0

@AlexZywicki私は*多くの理由を知りませんが、public *継承は* std :: unique_ptr ptr = new derived'がOKであることを意味するので危険です。それは実際にUBがあるときです。 – user2079303

0

私的に継承しているstd::vectorは、他の答えで提案されているように1つのアプローチです。

リサイズ可能なコンテナを使用する場合、リサイズ不可能なサイズで十分です。 std::vectorは、通常、データポインタの約4xサイズです。あなたはそれの半分にデータ+長へのポインタを格納することができます明らかに

template<class T> 
class dynarray 
{ 
    std::unique_ptr<T[]> data; 
    T*     end; // or size_t size 

    //TODO functions 
}; 

欠点は、あなたがそれ以外の場合はstd::vectorから継承することができることを、定型のすべてを再実装しなければならないということです。つまり、すべての定型文は非常に些細なことです。

関連する問題