2010-12-08 11 views
2

私はインターフェイスでC++イテレータを使用しようとしていますが、動作させることはできません。C++イテレータ、インターフェイス、ポインタ

私は、どのようなタイプでベクターの内容を選択するのか少し失われています。これはポインタである必要がありますか?私は新しい実装()をしなければならないのですか?要するに、それは私には不明であり、私はそれに関する有用な事例を見つけることができません。

ここには、インターフェイスと実装(.hファイル)があります。

class Interface{ 
public: 
virtual int method() = 0; 
}; 

class Implementation1 : public Interface{ 
    public: 
    int method(); 
}; 

class Implementation2 : public Interface{ 
    public: 
    int method(); 
}; 

.cppファイル:

#include "content.h" 

int Implementation1::method(){ 
    return 1; 
} 

int Implementation2::method(){ 
    return 2; 
} 

そして、私の主な機能:

#include "content.h" 
#include <vector> 
#include <iostream> 

using namespace std; 

int main(void) 
{ 
    // create the vector and put elements in it 
    vector<Interface*> elements; 
    elements.push_back(new Implementation1()); 
    elements.push_back(new Implementation1()); 
    elements.push_back(new Implementation2()); 

    // now iterate on them 

    vector<Interface*>::iterator iterator; 
    for(iterator = elements.begin(); iterator != elements.end(); ++iterator){ 
     *iterator->method(); 
    } 

    return 1; 
} 

compilatorが出力している:私は何について

main.cpp: In function ‘int main()’: main.cpp:19: error: request for member ‘method’ in ‘* iterator.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator-> with _Iterator = Interface**, _Container = std::vector >’, which is of non-class type ‘Interface*’

任意のアイデアここで間違っている?

+0

「働いていない」とはどういう意味ですか? – kennytm

+0

コンパイルに失敗しました。私はg ++の出力を追加しました。 –

答えて

11

変更*iterator->method();

(*iterator)->method();前者デリファレンスiterator-のリターン>方法()。 Interface *にはmethod()はありません。何もありません。

イテレータを逆参照してポインタを取得し、ITを参照解除したいとします。

あなたは基本的にIterator **と同じことをしていますので、それに応じて行動してください。

+3

「*」よりも ' - >'が優先されるように、 '2 * 2 + 2'の' * 'と同じ方法で' + 'より優先順位が高くなります。 – Thanatos

0

があり、あなたが何をやったかについて、本質的に無効なものは何もないですが、生のポインタのベクトルを作成することが一般的に悪い考えです、あなたはshared_ptrのようなポインタ(「スマート」ポインタを)強制所有権を使用する必要があります(*iterator)->method();

0

を試してみてください。また、イテレータの参照を解除する必要もなく、直接method()を直接提供する必要があります。しかし、私はこのコードと直接コンパイルできないものは見当たりません。*iterator->method()を除いて、前回の参照解除が本当に低い優先順位を持っていて、あなたは*(iterator->method())をコンパイルできません。

+0

生ポインタのベクトルを誤差優先度(すなわち、スマートポインタのベクトルと比較して)が最適以下であるという発言は正しいが、必要でない参照カウントスマートポインタを示唆することは、効率に関してはまだ最適ではないが、それでもなお悪い)。より良い解決策があります: 'boost :: ptr_vector'や' unique_ptr'(C++ 0x)のようなスマートポインタの単純なベクトルです。 – Kos

2

+1反復子のコンパイルエラーについては、いい説明です。以前の質問については、

I'm a bit lost with what type to choose for the vector contents. Is this need to be a pointer ? do I have to make a "new Implementation()"?

はい、これはポインタでなければなりません。理由は単純です:タイプTのベクトルは、サブタイプではなくTの要素のみを格納し、所有しています。それには良い理由があります(サブクラスのサイズが異なる場合はどうなりますか?)。

したがって、オブジェクトをどこかに格納し、ポインタをベクトルに保持する必要があります。実際、フリーストアにoperator newで保存するのが最も簡単な方法です。

あなたの生活を少しでも簡単にしたい場合は、boost::ptr_vectorをご利用ください。

+2

スマートポインタを使用することもできます。例えば、あなたの必要に応じて、 'vector >'を使うことができます。 auto_ptrやscoped_ptrは使わないでください。彼らは動作するように見えるかもしれませんが、合法的なベクトルコンテンツではありません。 –

+0

合意(しかしそれはまだC++ 0xなので、 'ptr_vector'は私のNo.1勧告ATMです)。 – Kos

関連する問題