避免每个成员变量

时间:2017-05-29 13:43:24

标签: c++

我编写了辅助函数来设置顶点属性。正如您所看到的,3个函数基本相同,只是每个函数设置顶点的不同成员变量。因为它反对DRY原则并且看起来很难看,我想将它们结合起来。

void setPositions(const int offset, const sf::Vector2f (&positions)[vertexCount]) {
    int index = ensureSizeAndGetIndex(offset);
    for(int i = 0; i < vertexCount; i++) {
        vertices[index + i].position = positions[i];
    }
}

void setTexCoords(const int offset, const sf::Vector2f (&texCoords)[vertexCount]) {
    int index = ensureSizeAndGetIndex(offset);
    for(int i = 0; i < vertexCount; i++) {
        vertices[index + i].texCoords = texCoords[i];
    }
}

void setColors(const int offset, const sf::Color (&colors)[vertexCount]) {
    int index = ensureSizeAndGetIndex(offset);
    for(int i = 0; i < vertexCount; i++) {
        vertices[index + i].color = colors[i];
    }
}

我考虑的事情:

  • 模板不会在这里工作,因为他们不处理成员变量
  • 我可以通过传递要使用的变量的bool标志来组合前两个函数。但这对第三个功能没有帮助。
  • 我可以添加指向顶点类的成员变量的指针和一个可供选择的枚举,但这会太多(性能)开销
  • Lambda可能,元编程可能吗?

对这里最干净的解决方案感兴趣。

1 个答案:

答案 0 :(得分:2)

如果texCoordspositioncolor属于同一类型,则解决方案非常简单。类成员指针。

假设有问题的类看起来像这样:

class V {
public:

   int texCoords;
   int position;
   int color;
};

然后,每个成员函数都成为一个提供适当的类成员指针的包装器。例如,setTexCoords变为

void setTexCoords(const int offset, const sf::Vector2f (&texCoords)[vertexCount]) {
  setCommon(offset, texCoords, &V::texCoords);
}

其他两个包装器是类似的,公共代码变为:

void setCommon(const int offset, const sf::Vector2f (&texCoords)[vertexCount],
               int V::*member) {
    int index = ensureSizeAndGetIndex(offset);
    for(int i = 0; i < vertexCount; i++) {
        vertices[index + i].*member = texCoords[i];
    }
}

类成员指针看起来像常规指针,它们共享相同的原则,但它们不是传统的指针,有必要完全理解它们的工作原理。有关更多信息,请参阅您的C ++书籍。