gpt4 book ai didi

c++ - 这种情况下合适的设计模式是什么?

转载 作者:太空狗 更新时间:2023-10-29 21:27:36 25 4
gpt4 key购买 nike

我正在尝试实现一个模型 (gfx) 类,但我似乎找不到适合它的设计。

我有的是:[伪代码]

class Material {
public:
virtual void SetPerFrameInfo(void* pData)=0;
//[...]
}

class SpecificMaterial : public Material {
public:
void SetPerFrameInfo(void* pData);
//[...]
}

void SpecificMaterial::SetPerFrameInfo(void* pData) {
ThisMaterialPerFrameInfoStruct* pInfo = (ThisMaterialPerFrameInfoStruct*)pData;
//[...]
}

class Model {
public:
Model(Material* pMaterial){m_pMatirial = pMaterial;}
void Draw();
private:
Material* m_pMaterial
//[...]
}

void Model::Draw() {
PerFrameInformation info;
m_pMaterial->SetPerFrameInfo(&info);
}

使用方法:

Material* pMaterial = new SpecificMaterial();
Model someModel(pMaterial);

如您所见,我有两个主要问题:

1) 传递给SetPerFrameInfo()的struct类型取决于实际素材,应该怎么填写?

2) 模型类可能需要一些其他数据成员,具体取决于实际 Material ,因为对于某些 Material ,我可能决定实现计时器,而对于某些 Material ,我可能不会。在所有 Material 的模型类中拥有数据成员将是一种内存浪费。

请帮忙,我似乎找不到任何合适的设计模式。

最佳答案

1.) 我认为您遇到的问题是因为试图在基类中放置太多内容。由于模型在调用 SetPerFrameInfo 函数时需要知道它使用的是什么特定 Material 类型,为什么不只为每个 Material 派生类提供其自己的 Set..() 函数,该函数采用正确的类型而不是 void*?因为 Material 基类无法与其每帧信息进行交互(它是 void*),那么为什么要将其泛化到基类中?

2.) 只需将特定于 Material 的数据成员放入派生的 Material 类中。我假设每个 Material 实例都对应一个唯一的模型,因此模型的特定于 Material 的信息应该在其 Material 派生类中。

针对您的澄清:

好吧,我误解了两个类之间的关系。基本上,在理想情况下,您需要一组不知道模型细节的 Material 类,以及一组可以使用任何 Material 但不知道 Material 细节的模型。因此,您可能希望将粗糙 Material 实例应用于六个不同的模型。

我不认为有任何问题,如果每个 Material 实例由多个模型共享并且每个模型实例对不同的 Material 一无所知,则需要第三个每个模型对象来存储计时器或任何实例数据绘图所需。因此,每个模型都会收到自己的 AppliedMaterial 对象,该对象指向共享的 Material 实例以及将 Material 应用于该模型所需的数据成员。每种 Material 类型都必须有不同的 AppliedMaterial 子类,存储与每种 Material 相关的数据值。使用第三个上下文对象的示例:

struct GlossMaterialContext
{
Timer t;
int someContextValue;
};

class GlossMaterial : Material
{
void * NewApplicator() { return new GlossMaterialContext; }
void FreeApplicator(void *applicator) { delete (GlossMaterialContext*)applicator; }
void ApplyMaterial(void *applicator)
{
// Set up shader...
// Apply texture...
}
};

class 3DModel
{
Material *material;
void *materialContext;

void SetMaterial(Material *m)
{
material = m;
materialContext = m->NewApplicator();
}
void Draw()
{
material->ApplyMaterial(materialContext);
}
};

这不是一种非常干净的技术。我总觉得处理 void* 指针是一件麻烦事。您还可以让第三个上下文对象基于一个类,例如:

class AppliedGlossMaterial : AppliedMaterial

和:

class GlossMaterial : Material
{
AppliedMaterial * NewApplicator() { return new AppliedGlossMaterial; }
...

如果数据成员同时依赖于模型类型和 Material 类型,那么您的模型和 Material 的耦合度太高,以至于无法将它们放入相互之间不了解的单独类中。您必须创建模型的子类:Glossy3DModel、Rough3DModel 等。

关于c++ - 这种情况下合适的设计模式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8858294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com