首页 > 解决方案 > C++ 类设计问题。将类与其他类和数量相关联

问题描述

我有以下材料类供 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);

以上是我发现实现所需行为的一种方法,但是感觉真的很糟糕的代码,而且我不确定放置 new 运算符的性能与堆栈分配相比如何。

性能至关重要,因为我可能会在大约 10 秒的跨度内创建约 8.4 亿个 BlockTest 对象,这就是为什么我不能只在每个类上都有一个 Material* 数组并使用 new 运算符构造每个材质。

BlockTest 对象的内存以 65,536 个块的形式预先分配,然后使用placement new 运算符构建以最小化堆分配成本,这本身不会导致任何性能问题。

我真正需要发生的事情。

Material 子类指定了针对每种材质类型(本质上是纹理 UV 贴图、MATERIAL_ID 等)而变化的常量数据,因此这些变量可以是静态的,只需通过静态方法访问即可,无需实例化实例而无需内存开销。然而,对于每个 BlockTest 类,它还需要将它由(1 到 4 种不同材料之间)组成的每个 Material 子类与一个数量相关联。

例如:BlockTest* b1 由 3 种材料组成。

BlockTest* b2 由 2 种材料组成。

对于每个 BlockTest 实例,它需要访问它包含的每个 Material 的静态方法(方法始终相同并在 Material 基类中定义),并且它需要一种将这些材料中的每一个与其数量相关联的方法。

我认为模板可能是解决此问题的更好方法,但是我不确定如何将每个模板类与数量相关联。此外,如果 BlockTest 类是模板化的,我需要一种方法来存储具有不同模板参数的 BlockTest* 对象数组。

标签: c++objectclass-design

解决方案


推荐阅读