点运算符和get方法之间的区别

时间:2015-06-29 23:22:26

标签: c++

我有一个矢量类

class Vector {
public:
    double x, y, z;
    Vector add(Vector v) {
        return Vector(x+v.x, y+v.y, z+v.z);
    }
};

我有一个Ray类

class Ray {
public:
    Vector origin, direction;
    Vector getOrigin() { return origin; }
};

在某些方法中,我这样做:

Vector x = ray.origin().add(normal); // doesn't work
Vector y = ray.getRayOrigin().add(normal); // works

错误消息:类型向量不提供调用操作符

为什么我不能直接访问矢量?

3 个答案:

答案 0 :(得分:8)

因为origin不是函数。访问它时删除括号。

答案 1 :(得分:2)

Xīcò有正确的解决方案,但不是正确的症状。

origin不一定是一个功能。 Vector类可以重载operator()并被调用,就像它是一个函数一样,这就是编译器试图传递的消息。

ray.origin允许任何人对ray的{​​{1}}成员做任何事情,包括可能对origin有害的事情。非常不酷。 setter和getter的目的是规范对成员变量的访问。目标是自卫。

OP的ray方法不返回原点。它返回原始副本。恶意的cretin可以在不破坏getOrigin的情况下对副本执行任何操作。这通常是正确的方式,除非要返回的对象被修改或复制成本过高。在该修改案例中,使用私有数据锁定返回的对象,并使用它自己的getter和setter。在昂贵的复制案例中,将返回值声明为ray以减少损坏的可能性。

在允许进行更改之前,优秀的设置者将审核const成员的所有输入。如果调用者尝试输入与origin不一致的值,origin可以将其降低。

通过ray直接访问origin可以.无法进行任何辩护。它还可以防止ray更改原始实现而不会破坏原始用户。

这些是否与rayVector这样的简单类有关,是编码风格和必要性的问题,但将数据访问锁定到最低限度是一个很好的习惯。在开发复杂的软件时必须深入了解。

答案 2 :(得分:1)

class Vector {
  public:
    double x, y, z;
    Vector add(Vector v) {
      return Vector(x+v.x, y+v.y, z+v.z);
    }
};

class Ray {
  public:
    Vector origin, direction;
    Vector getOrigin() { return origin; }
    Vector& getOrigin2() { return origin; }
};

int main() {
    Ray ray;
    Vector v1 = ray.origin;  // returns origin member
    Vector v2 = ray.getOrigin(); // returns a copy of origin member
    Vector v3 = ray.getOrigin2(); // same as v1, returns origin member
}