从基类指针获取模板派生类的值
Getting template derive class's value from base class pointer
我有一个工具允许用户编辑glsl的统一变量值,我需要将所有数据存储在std::vector中。
由于所有变量的值都有不同的变量类型(vec2, vec3, vec4, mat2...等),将它们存储在单个容器中是一个挑战。我决定采用这种方法
class BaseData
{
public:
};
template <typename T>
class Data: public BaseData
{
public:
Data(TypeEnum enumType, T valueIN): value(valueIN), type(enumType)
{
}
T GetValue()
{
return value;
}
TypeEnum GetType()
{
return type;
}
private:
T value;
TypeEnum type;
};
class Material
{
Material(std::vector<Base*> valueVec)
{
for(auto i : valueVec)
{
switch(i->GetType())
{
case BaseColor:
SetBaseColor(i->GetValue());//need something like this
break;
case BaseTexture:
SetBaseTexture(i->GetValue());//need something like this
break;
case EmissionColor:
SetEmissionFactor(i->GetValue());//need something like this
break;
case EmissionTexture:
SetEmissionTexture(i->GetValue());//need something like this
break;
case Material_nProps_NormalTexture:
SetNormalMap(i->GetValue());//need something like this
}
}
}
}
int main()
{
std::vector<BaseData*> uniformValue;
uniformValue.push_back(new Data(BaseColor, glm::vec4(1,2,3,4)));
uniformValue.push_back(new Data(BaseTexture, 0));
uniformValue.push_back(new Data(EmissionColor, glm::vec3(1,1,1)));
uniformValue.push_back(new Data(BaseTexture, 1));
Material PBR(uniformValue);
}
但问题是,现在如何从基指针获取值而不将其强制转换为正确的派生类型指针?
如果不想强制转换,可以使用命令模式,其中每个 GLSL 属性类接收指向 Material 对象的指针并执行相应的操作。每个命令都需要访问材质的某些内部结构。下面的代码对此进行了说明。(请注意,一切都是公开的,只是为了简单起见)。
struct Material; // forward declaration
struct GlslPropertyBase {
virtual ~GlslPropertyBase() {}
virtual void Execute(Material* m) = 0;
};
struct Material {
void SetBaseColor(Vec3 col) { /* Do something */ }
void SetBaseTexture(GLuint uid) { /* Do something */ }
Material(std::vector<GlslPropertyBase*> properties) {
for (GlslPropertyBase* property : properties)
property->Execute(this);
}
};
struct GlSlBaseColor : GlslPropertyBase {
Vec3 color;
GlSlBaseColor(float r, float g, float b) : color(r, g, b) {}
void Execute(Material* m) { m->SetBaseColor(color); }
};
struct GlSlBaseTexture : GlslPropertyBase {
GLuint uid;
GlSlBaseTexture(GLuint uid) : uid(uid) {}
void Execute(Material* m) { m->SetBaseTexture(uid); }
};
int main() {
std::vector<GlslPropertyBase*> properties;
properties.push_back(new GlSlBaseColor(1, 2, 3));
properties.push_back(new GlSlBaseTexture(1));
Material PBR(properties);
// delete heap objects...
}
这只是一种简单的方法(和实现),用于处理存储在单个向量中的异构 glsl 属性,而无需强制转换,这可能是@francesco在他的答案末尾建议的。
相关文章:
- 如何通过派生类函数更改基类中的向量
- 如何使用基类指针引用派生类成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 如果基类包含双指针成员,则派生类的构造函数
- 为什么此派生对象无法访问基类的后递减方法?
- 使用基类中的派生方法运行线程,而无需使用模板
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 在派生类中使用基类的私有成员变量的最佳方法
- 基类和派生类的多态赋值运算符
- 如何在从抽象基派生的类中实现相同的方法?
- 基类的填充将被复制到派生类中
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 指向基类派生类的 std::unique_ptr 的指针
- 为什么基类数据在派生类数据之前初始化
- c++ 派生基类 Friend 函数访问父级上的私有函数
- 如何将基类替换为派生基类
- 当基类未指定构造函数时,如何使用仅具有带参数的构造函数的类派生基类?
- 解析公用派生基类模板中的函数模板名称时出错"Not declared in this scope"