我有以下Material类要被BlockTest类使用。 Material 类本身永远不会被使用,它只是为所有子类提供一个接口来实现。 因此Material类有可能是一个抽象类。
class Material {
public:
Material() : m_nQuantity(0) {}
Material(uint8_t amount) : m_nQuantity(amount) {}
virtual ~Material() {}
virtual Vector2D* getTextureTop() {
static Vector2D vector(0.0f, 0.0f);
return &vector;
}
virtual uint16_t getMaterialId() {
return 0;
}
uint8_t getQuantity() {
return m_nQuantity;
}
uint8_t m_nQuantity;
};
class GrassMaterial : public Material {
public:
GrassMaterial () : m_nQuantity(0) {}
GrassMaterial (uint8_t amount) : Material(amount) {}
virtual ~GrassMaterial () {}
virtual Vector2D* getTextureTop() {
static Vector2D vector(0.5f, 0.5f);
return &vector;
}
virtual uint16_t getMaterialId() {
return GRASS_BLOCK_ID;
}
uint8_t getQuantity() {
return m_nQuantity;
}
};
Block 类将需要对最多 4 个不同的 Material 子类进行引用,这些子类对于 Block 类的每个实例来说都是不同的。
class BlockTest {
public:
void render() {
std::cout << "BlockTest(Material&& m1, Material&& m2)" << std::endl;
std::cout << m_m[0].getTextureTop()->m_x << ":" << m_m[0].getTextureTop()->m_y << std::endl;
std::cout << (int)m_m[0].getQuantity() << std::endl;
std::cout << m_m[1].getTextureTop()->m_x << ":" << m_m[1].getTextureTop()->m_y << std::endl;
std::cout << (int)m_m[1].getQuantity() << std::endl;
}
BlockTest() {}
BlockTest(const BlockTest &obj) = delete;
~BlockTest() {
m_m[0].m_nQuantity = 255;
m_m[1].m_nQuantity = 255;
}
Material m_m[4];
};
使用方法。
BlockTest* bt = new BlockTest();
Material* m1 = new (&(b1->m_m[0])) GrassMaterial(54);
Material* m2 = new (&(b1->m_m[0])) StoneMaterial(84);
以上是我找到的一种实现预期行为的方法,但是感觉代码真的很糟糕,而且我也不确定放置新操作符的性能与堆栈分配相比如何。
性能是至关重要的,因为我可能会在10秒左右的时间内创建约8.4亿个BlockTest对象,这就是为什么我不能在每个类上都有一个Material*数组,并用new操作符来构造每个材料。
BlockTest对象的内存是以65,536块为单位预分配的,然后使用position new操作符来构造,以最大限度地降低堆分配成本,这本身并不会造成任何性能问题。
我实际需要发生的是。
Material子类为每一种Material指定了不同的常量数据(本质上是纹理UV贴图,matial_ID等),所以这些变量可以是静态的,只需通过静态方法访问即可,不需要实例化,没有任何内存开销。 然而对于每个BlockTest类来说,它还需要将它所组成的每个Material子类(1到4个不同的材质)与一个数量关联起来。
例如:BlockTest* b1由3个Materials组成。
BlockTest* b2由2种材料组成。
对于每个BlockTest实例,它将需要访问它所包含的每个材料的静态方法(方法总是相同的,并在材料基类中定义),它将需要一种方法来关联这些材料的数量。
我想模板可能是一个更好的方法,但是我不确定如何将每个模板类与数量关联起来。 另外,如果BlockTest类是模板化的,我需要一种方法来存储一个具有不同模板参数的BlockTest*对象数组。