2017-01-08 26 views
3

我正在练习班,我创建了一个程序,创建一个向量并计算它的大小。我将代码分开,以便一个类是矢量类,另一个类处理数学。我的问题是,这是不正确的?为了能够使用它,我必须实例化我的数学类,并且它看起来很笨重,尽管它很有用。我必须实例化这个类吗?或者这是责任分离的错误?

主营:

int main() 
{ 
    // Instantiate math library... ? 
    Math math; // <-- Instantiating math library here 
    Vector3D *test = new Vector3D("Test vector 1", 0, 0, 1); 
    printVector(test); 

    // Calling math library to calculate magnitude 
    std::cout << "Test vector 1 magnitude: " << math.magnitude(test) << std::endl; 


    return 0; 
} 

Vector类:

class Vector3D { 
    private: 
     std::string  name; 
     double   x; 
     double   y; 
     double   z; 

    public: 
     Vector3D(); 
     Vector3D(std::string, double, double, double); 

     // Setters 
     void setName(std::string); 
     void setX(double); 
     void setY(double); 
     void setZ(double); 

     // Getters 
     std::string getName() const; 
     double getX() const; 
     double getY() const; 
     double getZ() const; 

     // Operators 
     Vector3D& operator *=(double s); // Scalar multiplication 
     Vector3D& operator /=(double s); // Scalar division 


}; 

数学类:

class Math { 
    public: 
     double magnitude(const Vector3D* v); 
}; 
+0

这并没有错,但面向对象编程背后的想法之一是将代码与它将操作的数据打包在一起。鉴于此,我认为将magnitude()作为Vector3D类的成员函数比保持它的独立性会更有用。 –

+0

太宽了。也许http://codereview.stackexchange.com/会更适合这个问题。 –

回答

2

额外类当然不是对C异常复杂++(参见,例如,这完全规范代码,用于生成随机数:https://stackoverflow.com/a/13445752/5478284

由于math类包含关于矢量,只功能没有相关的信息,你不应该实例化它:你可以使用静态函数。不过,就像其他答案中提到的那样,你基本上有一个命名空间,我建议设计这个命名空间以包含有用的矢量函数和Vector3D类。

此外,我会重新命名它,因为它目前的立场。 math是一个令人难以置信的广泛名称。 (也许这就是为什么在小型操作之前实例化它感觉如此糟糕。)

8

类用于封装状态。 Math没有状态,因此它应该是一个命名空间,而不是一个类。

6

我的问题是,这是不正确的?

根据Scott Meyers,non-member functions improve encapsulation

如果您可以使用非成员函数来实现函数,那最好这样做。

使用另一个类的成员函数来进行计算没有任何意义。最好使用namespace并在namespace中定义该功能。

1

你所拥有的第一个不可宽约的捆绑责任是在你的类中包含一个字符串。数学价值不应该有名字。第二个是setter的存在。第三个是你的获得者中的'获得'。

数学值类型应该在'int'之后建模,而不是'object'。

class Vector3D 
{ 

private: // fields 

    double _x; 
    double _y; 
    double _z; 

public: // constructors 

    constexpr explicit Vector3D (double const x, double const y, double const z) 
     : _x {x}, _y {y}, _z {z} { } 

public: // accessors 

    constexpr double x() const { return _x; } 
    constexpr double y() const { return _y; } 
    constexpr double z() const { return _z; } 

}; 

constexpr Vector3D operator * (Vector3D const left, double const right) 
{ 
    return Vector3D { left.x() * right, left.y() * right, left.z() * right }; 
} 

constexpr Vector3D operator/(Vector3D const left, double const right) 
{ 
    return Vector3D { left.x()/right, left.y()/right, left.z()/right }; 
} 


Vector3D & operator *= (Vector3D & left, double const right) 
{ 
    return left = left * right; 
} 

Vector3D & operator /= (Vector3D & left, double const right) 
{ 
    return left = left/right; 
} 

当你实例化一个vector3d时,你应该删除新的指针。只需将其构建在堆栈上:

auto const point = Vector3D (0, 0, 1); 

另外,请不要复制Java。

相关问题