0

AccidentalNoise ライブラリのシーケンサーを構築しようとしています。ユーザーはさまざまな種類のノイズ レイヤーを記述した XML ファイルを生成し、結果を得ることができます。C++ で継承がどのように機能するかについて頭を悩ませています。

残念ながら、サブクラス (この場合はCImplicitSphere ) のすべてのメソッドがスーパークラス ( CImplicitModuleBase )で定義されているわけではないため、ベクター値をすぐに初期化することに成功しませんでした ( CImplicitSphere.setCenter()が良い例です)。これは私がこれまでに得たものです:

std::vector<anl::CImplicitModuleBase *> layers;

anl::CImplicitSphere tmp;

tmp.setCenter(0.0,0.0,0.0,0.0,0.0,0.0);

layers.push_back(&tmp);

value = layers.back()->get(0.0,0.0,0.0);

しかし、「純粋な仮想メソッドが呼び出されました」というエラーが表示されます-それが私が行き詰まっているところです-型キャストする必要がありますか? それについてはいくつかの議論がありますが、それは悪い考えであることを示唆しているようです.

CImplicitSphereをレイヤー ベクトルで直接初期化し、サブクラス メソッドを参照できるように、コードを構造化するより良い方法はありますか?

完全なソース:

void ScalarTerrain::setupAccidentalNoise() {
printf("Making an array of noise functions\n");
std::vector<anl::CImplicitModuleBase *> layers;

try {
    printf("Getting data for next layer\n");
    pugi::xml_node layer = terrainData.child("layer");

    if(strcmp(layer.attribute("type").value(), "sphere") == 0) {
        printf("Layer is a sphere building a temp layer\n");
        anl::CImplicitSphere tmp;

        tmp.setCenter(
            layer.child("center").attribute("x").as_double(),
            layer.child("center").attribute("y").as_double(),
            layer.child("center").attribute("z").as_double(),
            layer.child("center").attribute("u").as_double(),
            layer.child("center").attribute("v").as_double(),
            layer.child("center").attribute("w").as_double()
        );

        layers.push_back(&tmp);
    }
     else {
        printf("Layer type not found\n");
    }


} catch (char * exception) {
    printf("Exception raised: %s\n", exception);
}
try {
    for(int z = 0; z < z_chunk; z++) {
        for(int y = 0; y < y_chunk; y++) {
            for(int x = 0; x < x_chunk; x++) {
                value = layers.back()->get(
                    (double) x/x_chunk * 2, 
                    (double) y/y_chunk * 2, 
                    (double) z/z_chunk * 2
                );

                tc.values[x][y][z] = value;

                if(value < -0.5) tc.materials[x][y][z] = 0;
                else if (value < 0) tc.materials[x][y][z] = 1;
                else if (value < 0.5) tc.materials[x][y][z] = 2;
                else tc.materials[x][y][z] = 3;
            }
        }
    }
} catch (char * exception) {
    printf("Exception raised: %s\n", exception);
}
}
4

1 に答える 1

0

これは機能しているように見え、ひどく醜いわけではありません。

void ScalarTerrain::setupAccidentalNoise() {
printf("Making an array of noise functions\n");
std::vector<anl::CImplicitModuleBase *> layers;
anl::CImplicitModuleBase * tmp;


//anl::CImplicitSphere thisLayer;

try {
    printf("Getting data for next layer\n");
    pugi::xml_node layer = terrainData.child("layer");

    if(strcmp(layer.attribute("type").value(), "sphere") == 0) {
        printf("Layer is a sphere building a temp layer\n");
        tmp = new anl::CImplicitSphere();

        dynamic_cast<anl::CImplicitSphere*>(tmp)->setCenter(
            layer.child("center").attribute("x").as_double(),
            layer.child("center").attribute("y").as_double(),
            layer.child("center").attribute("z").as_double(),
            layer.child("center").attribute("u").as_double(),
            layer.child("center").attribute("v").as_double(),
            layer.child("center").attribute("w").as_double()
        );

        layers.push_back(tmp);
    }
     else {
        printf("Layer type not found\n");
    }


} catch (char * exception) {
    printf("Exception raised: %s\n", exception);
}
try {
    printf("Iterating through blocks\n");

    for(int z = 0; z < z_chunk; z++) {
        for(int y = 0; y < y_chunk; y++) {
            for(int x = 0; x < x_chunk; x++) {
                printf("getting block value at %d %d %d\n",x,y,z);

                value = layers.back()->get(
                    (double) x/x_chunk * 2, 
                    (double) y/y_chunk * 2, 
                    (double) z/z_chunk * 2
                );

                tc.values[x][y][z] = value;

                if(value < -0.5) tc.materials[x][y][z] = 0;
                else if (value < 0) tc.materials[x][y][z] = 1;
                else if (value < 0.5) tc.materials[x][y][z] = 2;
                else tc.materials[x][y][z] = 3;
            }
        }
    }
} catch (char * exception) {
    printf("Exception raised: %s\n", exception);
}
}

これは物事を行う「正しい」方法ですか、それとも私は的外れですか?

于 2012-08-24T05:36:12.290 に答える