如何使用 for 循环从包含不同派生 class 的基 class 数组初始化对象?
How can I initialize objects from base class array, containing different derived classes, using a for loop?
我真的对 OOP 背后的想法感到惊讶,因为我发现更容易想到 classes 和对象,就好像它们是真实的一样。我有一个基础 class 牙齿和派生的 classes 用于不同的牙齿组(他们有自己的细节)。他们的构造函数将绘制的纹理作为参数;
对于上牙,它是这样的:
class Tooth
{
public:
Tooth(Texture &texture);
};
class Molar : public Tooth { };
class Premolar : public Tooth { };
class Frontal : public Tooth { };
main()
{
Molar *molar[6];
Premolar *premolar[4];
Frontal *frontal[6];
Texture uppertextures[8]; //only 8 textures, since the other half of the teeth are mirrored
Tooth* upperTeeth[16] = { molar[0], molar[1], molar[2], premolar[0], premolar[1], frontal[0], frontal[1], frontal[2], frontal[3], frontal[4], frontal[5], premolar[2], premolar[3], molar[3], molar[4], molar[5] }; // < the order in which the teeth have to be added to the graphic scene;
int x = 0 //for the position of the tooth on the screen;
int texture = 0; //we will need it to assign the textures in order;
for(int i = 0; i<16; i++)
{
upperTeeth[16] = new !?!?!?(uppertextures[i])
upperTeeth[16]->setPositionX(i+x) // some function for setting the position on the screen from left to right;
if(i<8) texture++; //setting the textures for the teeth on the left;
if(i>8) texture--; //setting the textures for the teeth on the right(the same, but in reverse order);
upperTeeth[16]->setPositionY(y)
}
}
如您所见,问题出在分配上。我想以创建 Base class 数组的相同方式创建 new[],并填写对象出现的派生 classes 的顺序。当然,如果你有完全不同的解决方案,你可以分享,但这是我能想到的最聪明的方法。
很多人会告诉您“拿一本教科书”的原因是因为 C++ 中有很多机器在运行。但是别担心,没有它你可以学到很多东西。实践可能是最好的学习方式。
...找到问题的解决方案需要考虑一些事项。
首先,是您设置的构造函数。你有 child class 继承自 class 的元素,后者具有带参数的构造函数。这不好,这基本上意味着您无法创建 child classes。如果你尝试,你只会得到错误。所以我已经将所有构造函数更改为“默认”以便它实际运行,但是你也应该制作 child 构建基础 class 的构造函数,比如
Molar(Texture& texture)
: Tooth(texture)
{
// ... do whatever here
}
然后是所有权。哪个class“拥有”牙齿数据?你有你的数组,但它们是指针数组,所以它们实际上并不拥有数据。因此,您可以在其他地方拥有数据,以确保它不会 trash-collected 在您的函数上下文之外。 或者 只是让数组实际包含牙齿 classes。我已经在我的解决方案中这样做了,因为它更简单。但是您可以看到 upperTeeth
仍然是一个指针数组,因为您可能不想拥有 objects.
的两个副本
Molar molar[6];
Premolar premolar[4];
Frontal frontal[12];
Texture uppertextures[8]; // Only 8 textures, since the other half of the teeth are mirrored
// The order in which the teeth have to be added to the graphic scene
Tooth *upperTeeth[16] = { &molar[0], &molar[1], &molar[2], &premolar[0], &premolar[1], &frontal[0], &frontal[1]
, &frontal[2], &frontal[3], &frontal[4], &frontal[5], &premolar[2], &premolar[3], &molar[3]
, &molar[4], &molar[5] };
在此示例中,数组将在离开上下文时被销毁。通过使用指针数组和 new 构造函数,您可以在方法完成后继续使用该数组,但要跟踪它并在不再需要时将其删除,也就是在析构函数。更简单的方法是在 main class.
的 Header 中定义与我的示例相同的“所有者数组”
最后是底部的逻辑位,我将您的代码替换为:
int x = 0; // For the position of the tooth on the screen;
int y = 0; // Why not a y variable as well?
int texture = 0; // We will need it to assign the textures in order;
for(int i = 0; i<16; i++) {
upperTeeth[i]->setPositionX(i + x); // Some function for setting the position on the screen from left to right;
if (i < 8) texture++; // Setting the textures for the teeth on the left;
if (i > 8) texture--; // Setting the textures for the teeth on the right(the same, but in reverse order);
upperTeeth[i]->setTexture(texture); // alternative to your constructor
upperTeeth[i]->setPositionY(y);
}
注意你错过了使用 [i]
而不是 [16]
的地方。或者,您可以使用
直接遍历数组
int i = 0;
for (auto tooth : upperTeeth) {
tooth->setPositionX(i); // you still need i for your case.
i++;
}
希望我能解决一些问题!
我终于做了我想做的事。这个问题纯粹是合乎逻辑的。对于所有说我不应该子类化的人 - 我已经制作了一个程序版本,其中没有派生 类 的牙齿,在某些时候我觉得它太局限了。现在我发布了有效的代码:
class Tooth
{
public:
Tooth(Texture &texture);
};
class Molar : public Tooth { };
class Premolar : public Tooth { };
class Frontal : public Tooth { };
main()
{
Molar *molar[6];
Premolar *premolar[4];
Frontal *frontal[6];
Texture texture[8]; //only 8 textures, since the other half of the teeth are mirrored
int toothindex[16] = { 0, 1, 2, 0, 1, 0, 1, 2, 3, 4, 5, 2, 3, 3, 4, 5 };
int textureindex = 0; //we will need it to assign the textures in order;
for(int i = 0; i<16; i++)
{
if(i < 3 || i>12)
molar[toothindex[i]] = new Molar(texture[index]);
if(i==3; i==4; i==11; i==12)
premolar[toothindex[i]] = new Premolar(texture[textureindex]);
if(i>4 && i<12) frontal[toothindex[i]] = new Frontal(texture[textureindex])
if(i<7) texture++;
if(i>7) texture--;
}
}
感谢您告诉我所谓的未定义行为并提出 if 语句。我所要做的就是创建一个整数数组,并用它来初始化 for 循环中的特定 类。现在看起来像这样:https://imgur.com/a/fghmb9Y
哦...因为我使用的是指针数组,对于任何寻求答案的人,不要忘记制作某种 for 循环来删除不需要的对象:
for (int i = 0; i<6; i++)
{
if(i<4) delete premolar[i];
delete molar[i];
delete frontal[i];
}
我真的对 OOP 背后的想法感到惊讶,因为我发现更容易想到 classes 和对象,就好像它们是真实的一样。我有一个基础 class 牙齿和派生的 classes 用于不同的牙齿组(他们有自己的细节)。他们的构造函数将绘制的纹理作为参数; 对于上牙,它是这样的:
class Tooth
{
public:
Tooth(Texture &texture);
};
class Molar : public Tooth { };
class Premolar : public Tooth { };
class Frontal : public Tooth { };
main()
{
Molar *molar[6];
Premolar *premolar[4];
Frontal *frontal[6];
Texture uppertextures[8]; //only 8 textures, since the other half of the teeth are mirrored
Tooth* upperTeeth[16] = { molar[0], molar[1], molar[2], premolar[0], premolar[1], frontal[0], frontal[1], frontal[2], frontal[3], frontal[4], frontal[5], premolar[2], premolar[3], molar[3], molar[4], molar[5] }; // < the order in which the teeth have to be added to the graphic scene;
int x = 0 //for the position of the tooth on the screen;
int texture = 0; //we will need it to assign the textures in order;
for(int i = 0; i<16; i++)
{
upperTeeth[16] = new !?!?!?(uppertextures[i])
upperTeeth[16]->setPositionX(i+x) // some function for setting the position on the screen from left to right;
if(i<8) texture++; //setting the textures for the teeth on the left;
if(i>8) texture--; //setting the textures for the teeth on the right(the same, but in reverse order);
upperTeeth[16]->setPositionY(y)
}
}
如您所见,问题出在分配上。我想以创建 Base class 数组的相同方式创建 new[],并填写对象出现的派生 classes 的顺序。当然,如果你有完全不同的解决方案,你可以分享,但这是我能想到的最聪明的方法。
很多人会告诉您“拿一本教科书”的原因是因为 C++ 中有很多机器在运行。但是别担心,没有它你可以学到很多东西。实践可能是最好的学习方式。
...找到问题的解决方案需要考虑一些事项。
首先,是您设置的构造函数。你有 child class 继承自 class 的元素,后者具有带参数的构造函数。这不好,这基本上意味着您无法创建 child classes。如果你尝试,你只会得到错误。所以我已经将所有构造函数更改为“默认”以便它实际运行,但是你也应该制作 child 构建基础 class 的构造函数,比如
Molar(Texture& texture)
: Tooth(texture)
{
// ... do whatever here
}
然后是所有权。哪个class“拥有”牙齿数据?你有你的数组,但它们是指针数组,所以它们实际上并不拥有数据。因此,您可以在其他地方拥有数据,以确保它不会 trash-collected 在您的函数上下文之外。 或者 只是让数组实际包含牙齿 classes。我已经在我的解决方案中这样做了,因为它更简单。但是您可以看到 upperTeeth
仍然是一个指针数组,因为您可能不想拥有 objects.
Molar molar[6];
Premolar premolar[4];
Frontal frontal[12];
Texture uppertextures[8]; // Only 8 textures, since the other half of the teeth are mirrored
// The order in which the teeth have to be added to the graphic scene
Tooth *upperTeeth[16] = { &molar[0], &molar[1], &molar[2], &premolar[0], &premolar[1], &frontal[0], &frontal[1]
, &frontal[2], &frontal[3], &frontal[4], &frontal[5], &premolar[2], &premolar[3], &molar[3]
, &molar[4], &molar[5] };
在此示例中,数组将在离开上下文时被销毁。通过使用指针数组和 new 构造函数,您可以在方法完成后继续使用该数组,但要跟踪它并在不再需要时将其删除,也就是在析构函数。更简单的方法是在 main class.
的 Header 中定义与我的示例相同的“所有者数组”最后是底部的逻辑位,我将您的代码替换为:
int x = 0; // For the position of the tooth on the screen;
int y = 0; // Why not a y variable as well?
int texture = 0; // We will need it to assign the textures in order;
for(int i = 0; i<16; i++) {
upperTeeth[i]->setPositionX(i + x); // Some function for setting the position on the screen from left to right;
if (i < 8) texture++; // Setting the textures for the teeth on the left;
if (i > 8) texture--; // Setting the textures for the teeth on the right(the same, but in reverse order);
upperTeeth[i]->setTexture(texture); // alternative to your constructor
upperTeeth[i]->setPositionY(y);
}
注意你错过了使用 [i]
而不是 [16]
的地方。或者,您可以使用
int i = 0;
for (auto tooth : upperTeeth) {
tooth->setPositionX(i); // you still need i for your case.
i++;
}
希望我能解决一些问题!
我终于做了我想做的事。这个问题纯粹是合乎逻辑的。对于所有说我不应该子类化的人 - 我已经制作了一个程序版本,其中没有派生 类 的牙齿,在某些时候我觉得它太局限了。现在我发布了有效的代码:
class Tooth
{
public:
Tooth(Texture &texture);
};
class Molar : public Tooth { };
class Premolar : public Tooth { };
class Frontal : public Tooth { };
main()
{
Molar *molar[6];
Premolar *premolar[4];
Frontal *frontal[6];
Texture texture[8]; //only 8 textures, since the other half of the teeth are mirrored
int toothindex[16] = { 0, 1, 2, 0, 1, 0, 1, 2, 3, 4, 5, 2, 3, 3, 4, 5 };
int textureindex = 0; //we will need it to assign the textures in order;
for(int i = 0; i<16; i++)
{
if(i < 3 || i>12)
molar[toothindex[i]] = new Molar(texture[index]);
if(i==3; i==4; i==11; i==12)
premolar[toothindex[i]] = new Premolar(texture[textureindex]);
if(i>4 && i<12) frontal[toothindex[i]] = new Frontal(texture[textureindex])
if(i<7) texture++;
if(i>7) texture--;
}
}
感谢您告诉我所谓的未定义行为并提出 if 语句。我所要做的就是创建一个整数数组,并用它来初始化 for 循环中的特定 类。现在看起来像这样:https://imgur.com/a/fghmb9Y
哦...因为我使用的是指针数组,对于任何寻求答案的人,不要忘记制作某种 for 循环来删除不需要的对象:
for (int i = 0; i<6; i++)
{
if(i<4) delete premolar[i];
delete molar[i];
delete frontal[i];
}