0

以下に示すようなクラスのセットがあります。ただし、追加の仮想メソッドで基本クラスを変更することなく、ユーザーがそれらから派生できるようにしたいと考えています。virtual int GetT(void){return 0;};クラスで宣言せずにコードを変更する方法はありAますか?

A問題をさらに説明するために、ユーザーがとB(またはAextBext) の両方を独自のメソッドで拡張できるようにしたいと思います。これらはAとで仮想メソッドとして定義されていませんB。基本クラスへのポインターを派生クラスのポインターにキャストできるキャストメソッドを探しています。本質的に、派生クラスへのポインターが含まれているdynamic_cast<Aext*>(Trajectory[i])場合、つまり.Trajectory[i]Aext

class A {
    public:
    int a;
    A(int& ca) {a=ca;}
    virtual int GetT(void){return 0;};
};

class B{
    public:
    boost::ptr_vector<A> Trajectory;
    void PushBackStatePoint(int& ca);
};

void B::PushBackStatePoint(int& ca) {
    Trajectory.push_back(new A(ca));
}

class Aext: public A {
    public:
    int t;
    Aext(int& ca, int& ct) : A(ca) {t=ct;}
    virtual int GetT(void) {return t;}
};

class Bext: public B {
    public:
    void PushBackStatePoint(int& ca, int &ct);
    int GetFirstElement(void){return Trajectory[0].GetT();}
};

void Bext::PushBackStatePoint(int& ca, int &ct) {
    Trajectory.push_back(new Aext(ca,ct));

}

int main(){     
    Bext MyB;
    int a(5);
    int t(3);
    MyB.PushBackStatePoint(a,t);
    std::cout << MyB.GetFirstElement();
}
4

2 に答える 2

1

次のように、基本クラスでメソッドを純粋な仮想として定義できます。

class A {
    public:
    int a;
    A(int& ca) : a(ca) {}
    virtual int GetT() = 0;
};

これにより、派生クラスはGetT()を実装する必要があり、クラスAが抽象になります。

また、初期化リストを使用するようにコンストラクターを変更したことにも注意してください。これは、クラスメンバーを初期化するためのより良い方法です。

これは少し話題から外れているかもしれませんが、次のように、push_backを実行する方法を改善して、軌道ベクトルをより適切にカプセル化することができます。

class B{
public:
    boost::ptr_vector<A> Trajectory;
    void PushBackStatePoint(int& ca);
protected:
    void PushBackStatePoint(A *a) { Trajectory.push_back(a); }
    A getTrajectoryElement(int index) { return Trajectory[index]; }
};

void B::PushBackStatePoint(int& ca) {
    PushBackStatePoint(new A(ca));
}

class Bext: public B {
    public:
    void PushBackStatePoint(int& ca, int &ct);
    int GetFirstElement(void){return getTrajectoryElement(0).GetT();}
};

void Bext::PushBackStatePoint(int& ca, int &ct) {
    PushBackStatePoint(new Aext(ca,ct));
}

このように、基本クラスの属性はその中でのみ操作されます。

于 2012-06-08T09:47:50.343 に答える
1

メソッドを次のように記述した場合GetT:

virtual int GetT() = 0;

...それ以外の:

virtual int GetT(void){return 0;}

クラス A はそのままですが、すべてのユーザーが各自のクラスに独自の GetT メソッドを実装するようにします。また、クラス A からオブジェクトを作成することはできません。

したがって、私が本当に探しているのは、基本クラスへのポインターを派生クラスのポインターにキャストするためのある種のキャストメソッドです。

後でクラス A または B のオブジェクトを区別したい場合は、次のようにする必要があります。

A * ptrA = dynamic_cast<A*>( Trajectory[ 0 ] );
B * ptrB = dynamic_cast<B*>( Trajectory[ 0 ] );

if ( ptrA != NULL ) {
    // more things..
}
else
if ( ptrB != NULL ) {
    // more things..
}

これがあなたが探している答えかどうかはわかりません。とにかく、これが役立つことを願っています。

于 2012-06-08T09:49:09.043 に答える