2

注: これは、このエントリのほぼ複製です: 抽象クラスとポインタ

仮想クラスのベクトルを作成する必要があります。ここでアイデア:

#include <vector>
using namespace std;

class VirtualFoo {
protected:
    VirtualFoo();
    virtual ~VirtualFoo();
public:
    virtual void doStuff()=0;
};

class ConcreteFoo: public VirtualFoo {
public:
    ConcreteFoo(double a);
    virtual ~ConcreteFoo();
    void doStuff();
private:
    double a;
};

class Foo {
public:
    Foo(std::vector<VirtualFoo> foos);
    virtual ~Foo();
    void doAllStuff();
protected:
    std::vector<VirtualFoo> foos;
};

そして、私はそれを次のように使用したいと思います:

int main(int argc, char *argv[]){

    std::vector<ConcreteFoo> cfoos;
    cfoos.push_back(ConcreteFoo(1.0));
    cfoos.push_back(ConcreteFoo(2.0));

    Foo foo = Foo(cfoos);
    foo.doAllStuff();

}

もちろん、cfoos は VirtualFoo のベクトルであり、ConcreteFoo ではないため、これは機能しません。

ここで、VirtualFoo のベクトルではなく VirtualFoo* のベクトルを使用し、ポインタを ConcreteFoo のインスタンスにプッシュ バックすると、問題なく動作するようです。

ただ、それが最もクリーンな方法かどうかはわかりません。これを行う他の方法は考えていなかったようです。これは大丈夫ですか?

4

1 に答える 1

2

のポインタを持つベクトル std::vector<VirtualFoo*> cfoos;は問題ありません。抽象クラスをインスタンス化できないため、コンパイラは、抽象クラスを値として使用するベクターテンプレートをインスタンス化または特殊化できません。基本クラスのポインターで要素を指すことは問題ありません。これはリスコフの置換原則です(http://en.wikipedia.org/wiki/Liskov_substitution_principle

メモリ管理について心配する必要がないように、共有ポインタがより良い解決策であるという他の人からのコメントに同意します。

std::vector<shared_ptr<VirtualFoo>> cfoos;  
cfoos.push_back( shared_ptr<VirtualFoo> (new ConcreteFoo(1.0)) );   
cfoos.push_back( shared_ptr<VirtualFoo> (new ConcreteFoo(2.0)) );
于 2013-03-18T07:42:14.910 に答える