我正在尝试为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);
}
}
答案 0 :(得分: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);
}
}
这是“正确”的做事方式还是我没有做到?