2

みなさん、こんにちは。見てくれてありがとう。これは、ここに投稿された元の質問のフォローアップです。

このように定義した基本クラスがあります。

class DrawableShape
{
public:
    virtual HRESULT DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget)
    {
        return S_OK;
    }
};

このクラスを拡張する2つのクラスがありますが、どちらも似ているので、次の1つをリストします。

class MyD2DEllipse : public DrawableShape
{
private:
    D2D1_ELLIPSE data;
public:
    MyD2DEllipse();
    HRESULT DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget);
};

DrawShape関数は次のように実装されます。

HRESULT MyD2DEllipse::DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget)
{
    HRESULT hr = E_FAIL;
    ID2D1SolidColorBrush* m_pBrush;
    hr = m_pRenderTarget->CreateSolidColorBrush(
                D2D1::ColorF(D2D1::ColorF::OrangeRed),
                &m_pBrush
                );
    m_pRenderTarget->DrawEllipse(&data, m_pBrush, 10.f);
    return hr;
}

画面に乱数の楕円と長方形を描画したいので、最初にそれらの乱数を見つけて、そのサイズのDrawableShapeの配列を作成し(C ++ではオブジェクトを動的に割り当てることができないため)、親オブジェクトを次のように置き換えます。子オブジェクトを作成し、配列で描画関数を再度ランダムに呼び出します。私のコードは次のようになります。

    HRESULT Demo::OnRender()
    {
        HRESULT hr = S_OK;
        hr = CreateDeviceResources();

        if (SUCCEEDED(hr))
        {
            m_pRenderTarget->BeginDraw();
            m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
            m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));

            // Decide on # of primitives
        randEllipse = 1 + (rand() % 5);
        randRectangle = 1 + (rand() % 5);
        totalPrimitives = randEllipse + randRectangle;

        DrawableShape *shapes;
        shapes = new MyShape[totalPrimitives];

        for (int i=0; i<randEllipse; i++)
        {
            MyEllipse ellipse1;
            shapes[i] = ellipse1;
        }
        for (int i=randEllipse; i<(randEllipse + randRectangle); i++)
        {
            MyRectangle rect1;
            shapes[i] = rect1;
        }

        for (int i=0; i<totalPrimitives; i++)
        {
            hr = shapes[i].DrawMyShape(m_pRenderTarget);
        }
        hr = m_pRenderTarget->EndDraw();
    }
}

それはうまくいくはずですが、うまくいきません。また、これを書き留めた後、ある種のinit関数で配列を作成し、OnRender関数で配列の描画を呼び出す方がよいことに気付きました。助けてください!!


編集:さて、私はポインターで動作する形状を持っています、問題は配列の構築です。だから私はこのようなものを持っています:

    MyD2DRectangle rect1;
    MyD2DEllipse ell1;

    DrawableShape *shape1 = &rect1;
    DrawableShape *shape2 = &ell1;
    shape1->DrawShape(m_pRenderTarget);
    shape2->DrawShape(m_pRenderTarget);

それはそれ自体でうまくいくようです。スライスせずにDrawableShapeの配列を作成するにはどうすればよいですか?

4

1 に答える 1

4

shapesMyShapeインスタンスの配列です。shapes[i] = ellipse1;またはと言うとshapes[i] = rect1;、この割り当ての一部としてサブクラスデータが失われます。これは、C++ではスライスと呼ばれます。

そのため、への各呼び出しは、で定義されてshapes[i].DrawMyShape(m_pRenderTarget);いるように返されます。S_OKMyShape

C ++でポリモーフィズムを適切に使用するには、MyShapeインスタンスへのポインターまたは参照を使用する必要があります(通常はを使用して割り当てられますnew)。これを行うことが許可されていない場合(宿題?)、ポリモーフィズムなしでこれを行う方法を見つける必要があります。

于 2011-01-20T21:49:10.070 に答える