質問

ただ、疑問に思っているのは、私が直面している問題のために、ポインターのベクトルを作成することは可能ですか?もしそうなら、どのように?具体的には、イテレータと.begin()を一緒に使用すること、つまり、このベクトルをポインタのベクトルに変換するにはどうすればよいか

class c
{
     void virtual func();
};

class sc:public c
{
     void func(){cout<<"using func";}
};

sc cobj;

vector<c>cvect
cvect.push_back(cobj);
vector<c>::iterator citer

for(citer=cvect.begin();citer<cvect.end();citer++)
{
     citer->func();
}
役に立ちましたか?

解決 2

vector <c> cvectは、ポインターのベクトルではありません。タイプcのオブジェクトのベクトルです。 vector <c*> cvectが必要です。そしておそらくあなたが望む:

cvect.push_back( new c );

そして、イテレータを指定すると、次のようなものが必要になります:

(*it)->func();

もちろん、そもそもポインターのベクトルが必要ではなかった可能性が高いです...

他のヒント

もちろん。

vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
  (*citer)->func();
}

留意事項:

この例で行ったように動的に割り当てられたメモリを使用する場合は、自分の後にクリーンアップする必要があります

e.g。:

 for(...) { delete *i; }

これは、shared_ptr sのベクトル(boost::shared_ptrなど)を使用して単純化できます。これにはstd::auto_ptrを使用しないでください。機能しません(コンパイルすらしません)。

覚えておくべきもう1つのことは、ループ内のイテレーターを比較するために可能な限り<を使用しないでください。ランダムアクセスイテレーターをモデル化するイテレーターに対してのみ機能します。つまり、コードを使用例std::list

はい、可能です。実際、単一の型ではなくクラス階層全体のオブジェクトをベクターに含める場合は、ポインターを使用する必要があります 。 (ポインターを使用しないと、オブジェクトのスライシングという恐ろしい問題が発生します。すべてのオブジェクトは静かに表示されます。基本クラス型に変換されます。これはコンパイラによって診断されず、ほぼ間違いなくあなたが望むものではありません。)

class c
{
     void virtual func();
};

class sc:public c
{
     void func(){cout<<"using func";}
};

sc cobj;

vector<c*> cvect;             // Note the type is "c*"
cvect.push_back(&cobj);       // Note the "&"
vector<c*>::iterator citer;

for(citer=cvect.begin();citer != cvect.end();citer++)   // Use "!=" not "<"
{
     (*citer)->func();
}

ポインタのベクトルでは、独自のメモリ管理を行う必要があることに注意してください-ローカルオブジェクトを使用する場合(上記のように)、それらは抜けてはいけませんコンテナが行う前にスコープの。 newで作成されたオブジェクトへのポインタを使用する場合、コンテナが破棄される前に手動でdeleteする必要があります。この場合、 smart_ptr が提供するBoostなど、スマートポインターの使用を絶対に検討する必要があります。

はい、確かです。

// TestCPP.cpp : Defines the entry point for the console application.
//

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


using namespace std;

class c
{
public:
    void virtual func() = 0;
};

class sc:public c
{
public:
    void func(){cout<<"using func";}
};

int _tmain(int argc, _TCHAR* argv[])
{
    sc cobj;

    vector<c*> cvect;
    cvect.push_back(&cobj);
    vector<c*>::iterator citer;

    for(citer=cvect.begin();citer<cvect.end();citer++)
    {
        (*citer)->func();
    }

    return 0;
}

vector<c*> cvectの宣言とcvect.push_back(&cobj)の使用に注意してください。

提供されたコードから、イテレーターを間違った方法で使用しています。イテレータが指しているメンバーにアクセスするには、*citerの代わりにciterを使用する必要があります。

ポインタのベクトル用にvector<c*>を作成しました。次に、newを使用してcオブジェクトにメモリを割り当て、それらをベクトルにプッシュします。また、deleteする必要があることを忘れないでください。vector.clear()はcオブジェクトに割り当てられたメモリを解放しません。ここにcをポインターのベクトルとして保存する必要があります。そうしないと、仮想関数の呼び出しが機能しません。

ブーストポインタコンテナライブラリをお試しください。次のように、ポインターの通常のベクターに比べていくつかの利点があります。

my_container.push_back( 0 );            // throws bad_ptr 
ptr_vector<X> pvec; 
std::vector<X*> vec;
( *vec.begin() )->foo(); // call X::foo(), a bit clumsy
pvec.begin()->foo();     // no indirection needed
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top