2

Java のバックグラウンドがあり、C++ でのポリモーフィズムを理解しようとしています。具体的には、特定のメソッドを呼び出すために、スーパークラスによって定義された std ベクトル内の一連のサブクラスを反復処理する方法。私がやりたいことは、サブクラスが呼び出されるスーパークラスメソッドをオーバーライドすることです。ただし、C ++でそれを行う方法がわかりません。

セレリティに役立つコードを次に示します。

    class Tile {
    public:
            virtual void drawTile();
    }

    void Tile::drawTile() {} // not sure if this is needed?

    class Tile_Grass : public Tile {
    public:
            void drawTile();
    }

    void Tile_Grass::drawTile() { ... do stuff  ... }

私がやりたいことは次のとおりです。

    using namespace std;
    for (vector<Tile>::iterator itr = tileVector.begin(); itr != tileVector.end(); ++itr) {
            itr->drawTile(); // draws Tile_Grass, or any other sub class of Tile, but NOT Tile
    }

現在、for ループは「Tile::drawTile()」のみを呼び出しますが、「Tile_Grass::drawTile()」、または「tileVector」ベクトルにある Tile の別のサブクラスを呼び出すようにしたいと考えています。私は何が間違っているか、欠けていますか? 前もって感謝します!

4

2 に答える 2

4

のベクトルが必要Tile*になるか、さらに良いことに、std::unique_ptr<Tile>;

于 2013-06-19T01:04:56.360 に答える
3

Tile オブジェクトのコピーではなく、Tile へのポインタを使用して tileVector を宣言して設定する必要があります。

完全な Visual Studio 2012 サンプル プロジェクトを次に示します。

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

class Tile {
public:
       virtual void drawTile();
};

void Tile::drawTile() {} 

class Tile_Grass : public Tile  {
public:
       void drawTile();
};

void Tile_Grass::drawTile() {  std::cout << "Drawing Tile Grass" << std::endl;  }

int _tmain(int argc, _TCHAR* argv[])
{
    typedef std::vector<std::unique_ptr<Tile>> TileVector;

    TileVector vec;

    // add a few Tile_Grass objects
    vec.push_back(std::unique_ptr<Tile>(new Tile_Grass()));
    vec.push_back(std::unique_ptr<Tile>(new Tile_Grass()));
    vec.push_back(std::unique_ptr<Tile>(new Tile_Grass()));

    for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
        (*itr)->drawTile(); // draws Tile_Grass, or any other sub class of Tile, but NOT Tile
    }
    return 0;
}

これにより、Drawing Tile Grassが3 回出力されます。

代わりに、基本クラス Tile のインスタンスを含むようにベクターを定義すると、ベクターに格納されているオブジェクトは、元は派生 Tile_Grass オブジェクトとして作成されていたとしても、 spliced されます

typedef std::vector<Tile> TileValueVector;

TileValueVector vecv;

// add a few Tile_Grass objects
vecv.push_back(Tile_Grass());
vecv.push_back(Tile_Grass());
vecv.push_back(Tile_Grass());

for (auto itr = vecv.begin(); itr != vecv.end(); ++itr)
    itr->drawTile(); // draws Tile

これは以下を想定してDrawing Tileを 3 回印刷します。

void Tile::drawTile() { std::cout << "Drawing Tile" << std::endl; } 

スプライシングで起こることは、Tile_Grass のベース オブジェクト部分のみがベクター要素にコピーされることです。これは、そのベース オブジェクトのインスタンスを含むベクターが必要であると宣言したためです。

于 2013-06-19T01:10:35.253 に答える