2

我有一个名为“顶点”的类的两个版本,一个使用直接访问器获取坐标:

struct vertex
{
    // Coordinates
    std::array<double, 3> coords;

    // Direct accessors
    double & x;
    double & y;
    double & z;

    // Constructor
    template<typename... T> vertex(T &&... coordinates) :
        coords{{ std::forward<T>(coordinates)... }},
        x( coords[0] ), y( coords[1] ), z( coords[2] )
    { }
};

和其他使用访问功能的:

struct vertex
{
    // Coordinates
    std::array<double, 3> coords;

    // Access functions
    double & x() { return coords[0]; }
    double & y() { return coords[1]; }
    double & z() { return coords[2]; }

    // Constructor
    template<typename... T> vertex(T &&... coordinates) :
        coords{{ std::forward<T>(coordinates)... }}
    { }
};

对于这种特定情况,哪种方法更好?我将不胜感激任何其他建议。谢谢!

4

6 回答 6

2

我认为吸气剂更好。第一种方法创建更大尺寸的对象而没有真正的好处。

于 2012-08-09T18:12:10.637 回答
2

出于封装目的,我通常会遍历函数。

但这是一个非常特殊的情况,因为您正在处理顶点。如果您计划操作大量这些对象(渲染或变形网格),那么直接访问在性能方面有一些好处。

一些图形库在需要效率的实时环境中使用直接访问(一些书籍也建议)进行类似矢量的操作。

Ogre::Vector3为例。

尽管如此,我不会在你的第一个解决方案中做你正在做的事情。就像其他人说的那样,您无缘无故地将已用空间加倍(最终有很多顶点)。从我的角度来看,在高性能的背景下,这可能是最好的顶点:

class Vertex
{
public:
   double X;
   double Y;
   double Z;
};
于 2012-08-09T18:14:17.313 回答
1

我会使用该功能-它使您将来可以更轻松地改变主意。此外,您不能这样做:

double & x() { return coords[0]; }
double & y() { return coords[1]; }
double & z() { return coords[2]; }

double x() const { return coords[0]; }
double y() const { return coords[1]; }
double z() const { return coords[2]; }

与访问者。

于 2012-08-09T18:10:13.230 回答
1

好吧,我会说第一个更好,原因如下:

  • 您不太可能在顶点坐标上执行额外的处理 mid-get 或 mid-set。
  • 由于对顶点的操作通常在循环中完成,并且顶点通常与渲染有关,因此第一个选项(直接访问)可能会为您提供更好的性能。
  • 如果您要使用微不足道的 getter 和 setter 直接访问成员,那么封装不是必须的。这只是教条的面向对象。

话虽如此,第二种方法也有优势,例如不变的界面更能适应变化。我还是坚持第一个。

于 2012-08-09T18:14:49.513 回答
0

如果您真的想要对成员的直接写访问权(在这种情况下您似乎这样做并且可能是合适的),那么我建议您使用内联函数。如果您希望这样做,这使您可以灵活地分析并将额外的功能注入到未来的访问中。

于 2012-08-09T18:10:58.543 回答
0

我认为最好的解决方案是删除第二个选项的引用并添加设置器。但如果这些是唯一的选择,那么第二个会稍微好一些。

于 2012-08-09T18:11:45.410 回答