グローバルスコープにmyObjectsのベクターがあります。 std::vector<myObject>::const_iterator
を使用してベクトルをトラバースし、特定の要素を見つけるためにいくつかの比較を行うメソッドがあります。必要な要素が見つかったら、その要素へのポインタを返すことができます(ベクトルはグローバルスコープに存在します)。
&iterator
を返す場合、イテレータのアドレスまたはイテレータが指しているもののアドレスを返しますか?
const_iterator
をmyObjectにキャストして、そのアドレスを返す必要がありますか?
イテレータが指すもののアドレスを返します。
&(*iterator)
編集:混乱を解消するには:
vector <int> vec; // a global vector of ints
void f() {
vec.Push_back( 1 ); // add to the global vector
vector <int>::iterator it = vec.begin();
* it = 2; // change what was 1 to 2
int * p = &(*it); // get pointer to first element
* p = 3; // change what was 2 to 3
}
ポインターのベクトルまたは動的割り振りの必要はありません。
&iteratorを返すと、イテレーターのアドレスが返されます。要素を参照する方法を返したい場合は、イテレータ自体を返します。
イテレータ/ポインタを返すためにベクトルをグローバルにする必要はありませんが、ベクトル内の操作はイテレータを無効にできることに注意してください。たとえば、ベクトルに要素を追加すると、新しいsize()が予約メモリよりも大きい場合、ベクトル要素を別の位置に移動できます。ベクターから特定のアイテムの前に要素を削除すると、反復子は別の要素を参照します。
どちらの場合も、STLの実装によっては、ランダムエラーが頻繁に発生するため、デバッグが困難になる場合があります。
コメントの後の編集: 'はい、イテレータを返したくありませんでしたa)そのconst、およびb)確かにローカルの一時的なイテレータだけですか? – Krakkos '
反復子は、他の変数よりもローカルまたは一時的ではなく、コピー可能です。あなたはそれを返すことができ、コンパイラはポインタを使用する場合と同じようにコピーを作成します。
これで、const-nessが追加されました。呼び出し元が返された要素(ポインタまたはイテレータ)を介して変更を実行する場合は、非定数イテレータを使用する必要があります。 (イテレータの定義から「const_」を削除するだけです)。
イテレータを返すことはお勧めできません。反復子は、ベクトルの変更(反転\削除)が発生すると無効になります。また、イテレータはスタック上に作成されたローカルオブジェクトであるため、同じアドレスを返すことはまったく安全ではありません。ベクトル反復子ではなくmyObjectを使用することをお勧めします。
EDIT:オブジェクトが軽量の場合、オブジェクト自体を返す方が良いです。それ以外の場合は、ベクターに格納されているmyObjectへのポインターを返します。
ベクターがグローバルスコープ内にある限り、以下を返すことができます。
&(*iterator)
これは一般的にかなり危険であることに注意してください。ベクターがグローバルスコープから外れて破壊された場合、myObjectへのポインターは無効になります。これらの関数をより大きなプロジェクトの一部として作成している場合、非constポインターを返すと、戻り値が削除される可能性があります。これは、アプリケーションに対して未定義の壊滅的な影響を及ぼします。
これを次のように書き換えます。
myObject myFunction(const vector<myObject>& objects)
{
// find the object in question and return a copy
return *iterator;
}
返されたmyObjectを変更する必要がある場合は、値をポインターとして保存し、ヒープに割り当てます。
myObject* myFunction(const vector<myObject*>& objects)
{
return *iterator;
}
そうすることで、いつ破壊されるかを制御できます。
このような何かはあなたのアプリを壊します:
g_vector<tmpClass> myVector;
tmpClass t;
t.i = 30;
myVector.Push_back(t);
// my function returns a pointer to a value in myVector
std::auto_ptr<tmpClass> t2(myFunction());
ベクトルのdata関数を使用できます。
ベクトルの最初の要素へのポインターを返します。
最初の要素へのポインタではなく、インデックスが必要な場合は、たとえば次のようにすることができます。
//the index to the element that you want to receive its pointer:
int i = n; //(n is whatever integer you want)
std::vector<myObject> vec;
myObject* ptr_to_first = vec.data();
//or
std::vector<myObject>* vec;
myObject* ptr_to_first = vec->data();
//then
myObject element = ptr_to_first[i]; //element at index i
myObject* ptr_to_element = &element;
MyObjectのコピーをベクターに保存しています。したがって、myObjectのインスタンスをコピーするのは、コストのかかる操作ではないと思います。そして、最も安全なのは、関数からmyObjectのコピーを返すことだと思います。
たとえば、次のものがあるとします。
_std::vector<myObject>::const_iterator first = vObj.begin();
_
次に、ベクターの最初のオブジェクトは_*first
_です。アドレスを取得するには、&(*first)
を使用します。
ただし、STLの設計に合わせて、後でSTLアルゴリズムに渡す場合は、代わりにイテレータを返すことをお勧めします。
Dirkgentlyとanonの答えを参照して、begin関数の代わりにfront関数を呼び出すことができますので、not*
を記述する必要がありますが、&
のみを記述する必要があります。
コード例:
vector<myObject> vec; //You have a vector of your objects
myObject first = vec.front(); //returns reference, not iterator, to the first object in the vector so you had only to write the data type in the generic of your vector, i.e. myObject, and not all the iterator stuff and the vector again and :: of course
myObject* pointer_to_first_object = &first; //* between & and first is not there anymore, first is already the first object, not iterator to it.
イテレータが指すもののアドレスを返す必要があるかどうかはわかりません。必要なのは、ポインター自体です。この目的で_Ptrの使用を実装するSTLのイテレータークラス自体が表示されます。だから、ただやる:
return iterator._Ptr;